まず、コードに冗長性があります。diff
割り当てられていますが、使用されていません。あなたはそれを取り除くことができます:
def run_app(name, startr)
constant_var = name if startr == 1
some_name = modify name
compare(some_name, constant_var)
# recursive call
run_app(some_name, 0)
end
これを解決する標準的な方法は、その追加情報を渡すための追加パラメーターを追加することです。
def run_app(name, startr, constant_var)
some_name = modify name
compare(some_name, constant_var)
# recursive call
run_app(some_name, 0, constant_var)
end
次に、次のようにメソッドを呼び出す必要があります。
run_app(tmp = 'john', 1, tmp)
# or
run_app('john', 2, nil)
ただし、これにより大量の内部実装の詳細が呼び出し元に漏洩し、呼び出し元に大きな負担がかかります。たとえば、最初と 3 番目の引数が同じオブジェクトである必要があることを知る必要があります。1
ただし、2 番目の引数として渡された場合のみです。以外のものを渡す場合は、3 番目の引数として1
渡す必要があります。nil
誰かが電話をかけないようにする方法
run_app('john', 1, 'ringo')
# or
run_app(tmp = 'john', 2, tmp)
オプションのパラメータとデフォルトの引数を使用することで、これをわずかに改善できます。
def run_app(name, startr, constant_var = name if startr == 1)
some_name = modify name
compare(some_name, constant_var)
# recursive call
run_app(some_name, 0, constant_var)
end
これで、好きなように呼び出すことができます:
run_app('john', 1)
# or
run_app('john', 2)
ただし、次のように呼び出すこともできます。
run_app('john', 1, 'ringo')
# or
run_app(tmp = 'john', 2, tmp)
そこで、そのロジックをprivate
ヘルパー メソッドに移動し、パブリック メソッドに必要な API を提供します。
def run_app(name, startr)
constant_var = name if startr == 1
run_app_r(name, startr, constant_var)
end
private
def run_app_r(name, startr, constant_var)
some_name = modify name
compare(some_name, constant_var)
# recursive call
run_app_r(some_name, 0, constant_var)
end
次のように呼び出します。
run_app('john', 1)
# or
run_app('john', 2)
もちろん、今でも通話できます
run_app_r('john', 1, 'ringo')
# or
run_app_r(tmp = 'john', 2, tmp)
しかし、少なくとも、YARD のタグを使用するか、RDoc のタグを使用してドキュメントから完全に除外するなど、明確に文書化できる別の方法があります。private
@private
:nodoc:
run_app_r
メソッドが内部でのみ呼び出されることを意図しているにもかかわらず、どこからでもメソッドを呼び出すことができるという事実は、run_app
かなり面倒です。ネストされたメソッドをサポートする Scala のような言語では、run_app_r
メソッドをメソッド内に配置するだけですがrun_app
、Ruby はネストされたメソッドをサポートしていないため、別の方法を見つける必要があります: Proc
s はメソッド内でネストできます!
def run_app(name, startr)
constant_var = name if startr == 1
(run_app_r = ->(name, startr, constant_var; some_name) {
some_name = modify name
compare(some_name, constant_var)
# recursive call
run_app_r.(some_name, 0, constant_var)
}).(name, startr, constant_var)
end
次のように呼び出します。
run_app('john', 1)
# or
run_app('john', 2)
ブロックはクロージャであるため、明示的に渡す必要さえありませんconstant_var
。
def run_app(name, startr)
constant_var = name if startr == 1
(run_app_r = ->(name, startr; some_name) {
some_name = modify name
compare(some_name, constant_var)
# recursive call
run_app_r.(some_name, 0)
}).(name, startr)
end
次のように呼び出します。
run_app('john', 1)
# or
run_app('john', 2)
ただし、再帰には基本ケースがなく、無限にループするため、これはすべて意味がありません。というか、Ruby は適切な末尾呼び出しを保証していないため、スタック オーバーフローが発生します。