🚀

GitHub Copilot for Individuals はアンチパターンをどこまでリファクタしてくれるのか?

2023/04/29に公開

TL;DR

GitHub Japan の中の人が書いたらしいこの記事を見ていると、リファクタの章が。

https://ai-native-development.gitbook.io/docs/v/ja/basic/refactoring

そこで、こんな風に書くといい感じにリファクタしてくれることを知りました。

以下のサンプルは、先に紹介した記事からの抜粋です。

def calculate_sum(numbers):
    total = 0
    for number in numbers:
        total += number
    return total

# リファクタリングされた calculate_sum()を以下に書いてください
def calculate_sum(numbers):
    return sum(numbers)

では、一般的に良くないとされているコードを、Copilot はどこまでリファクタしてくれるのか?を検証しようという試みです。

今回はプログラミングをしたことがある人なら誰でも知ってる以下の 3 つのアンチパターンについて検証してみます。

  1. 意味不明な命名
  2. マジックナンバー
  3. アーリーリターン

なお、検証は GitHub Copilot の個人プランでやってます。なので、もしかするとビジネスプランだと結果が変わってくるかもしれません。

意味不明な命名

def kansuu1(a: int, b: int) -> int:
    return a + b

# リファクタリングされたkansuu1以下に書いてください

稀によくみる初心者が書いたようなコードですが、どうなるか。

なるほど。Coplilot さんはこの関数が他にどこで使われているか?までは把握してない可能性があり、それでなくても既存コードに影響が出にくい形で直しているのかもしれません。

では少し指示を具体的にします。

def kansuu1(a: int, b: int) -> int:
    return a + b

# 関数名や変数名を意味のあるものにしたkansuu1を作成してください

変数名だけ微妙に変わったけど、アンチパターンのままのコードができてしまいました。

もしかすると"名前を変える"という行為はプログラムのあちこちに影響を及ぼす可能性があるので Copilot としては避けているのかもしれません。

一応、ChatGPT にお願いしてみます。

ChatGPT はいい感じにリファクタを行なってくれました。

マジックナンバー

では次。これもまた稀によくみるマジックナンバーを使ったコードです。(まあ、今回は意味はわかるんですが…)

def print_fruit(fruit: int):
    if fruit == 0:
        print("apple")
    elif fruit == 1:
        print("Orange")
    elif fruit == 2:
        print("Banana")
    else:
        print("other")

# printFruit()で使われているマジックナンバーを解消したコードを以下に書いてください

するとマジックナンバーの定義自体はしてくれませんでしたが、こちらの意図を汲んでくれてはいますね。

ただ"printFruit()で"と命令しているので仕方ないかもです。

なので、もう少し丁寧に命令してみます。

予想は的中で、指示を具体的にすると今度は完璧なコードを作ってくれました。

では ChatCPT はどうか。

ChatCPT もいい感じにマジックナンバーを解消してくれたうえに、当初キャメルケースで書いていた関数名まで直してくれました(笑)

アーリーリターン

最後です。これもまた稀によくみる、アーリーリターンできていないコードです。

関数はマジックナンバーの章で使ったコードを再利用します。

def get_fruit_name(fruit: int)->str:
    fruit_name = ""
    APPLE = 0
    ORANGE = 1
    BANANA = 2
    if fruit == APPLE:
        fruit_name = "apple"
    elif fruit == ORANGE:
        fruit_name = "Orange"
    elif fruit == BANANA:
        fruit_name = "Banana"
    else:
        fruit_name = "other"
    return fruit_name

# リファクタリングされた get_fruit_name()を以下に書いてください

なるほど。これはこれでユニークなコードですが自分の意図とは若干違う形で修正されているので、指示を具体的にします。

LGTM!

いい感じに修正してくれています。

では最後に ChatGPT にもお願いしてみましょう。

はい、だいたい Copilot と同じ感じになりました。

おわりに

GitHub Copilot for Individuals たと、今回検証した 3 つのアンチパターンに関しては、命名以外については素晴らしい形で修正してくれました。

ただ命名についても先に述べた見解のとおりで、大きな影響を及ぼす可能性があるので修正を避けているのかもしれません。

この他にもアンチパターンについて試したものがあれば、ぜひ教えてください!

メンバー募集中!

サーバーサイド Kotlin コミュニティを作りました!

Kotlin ユーザーはぜひご参加ください!!

https://serverside-kt.connpass.com/

また関西在住のソフトウェア開発者を中心に、関西エンジニアコミュニティを一緒に盛り上げてくださる方を募集しています。

よろしければ Conpass からメンバー登録よろしくお願いいたします。

https://blessingsoftware.connpass.com/

Discussion