、ルビの方法でオプションのパラメータのデフォルト値は何ですか?
class MyClass
def index(arg1, arg2="hello")
end
end
それはClass#instance_method
、または何かのようないくつかの方法を介して、arg2
のデフォルト値を取得することは可能ですか?
、ルビの方法でオプションのパラメータのデフォルト値は何ですか?
class MyClass
def index(arg1, arg2="hello")
end
end
それはClass#instance_method
、または何かのようないくつかの方法を介して、arg2
のデフォルト値を取得することは可能ですか?
私はそのようなユーティリティが利用できない理由は、デフォルト引数の値が割り当てられなければならないときに評価されるということだと思います。したがって、それらを評価しようとすると副次的な影響が生じる可能性があります。
私はあなたにロシア政府の核計画について話教えてみましょう:いくつかの時間前
を、彼らはエラー防止およびメガの両方であるAA解決策を考え出すために超ハードコア、ロシアのハッカーを雇っ利用可能なすべての核を発射するか、単にシミュレーションを実行することができます。彼らは
launch_all_nukes
という1つのメソッドを作成することにしました。これはオプションでキーワード引数simulation_number:
を受け入れます。彼らは実装をREPLにロードし、コードを削除して敵のスパイが実際にどのように動作するかを決して知ることができないようにしました。過去数年のための
毎日、信頼できる専門家イワンは、彼が定期的IRBになりそうだ何の前に座っているとロシアの可能性を評価ギガ秘密の場所に移動します連邦は、相互に保証された破壊を生き延びた。
$: launch_all_nukes simulation_number: 1
...
ちょうど別の正規の日。$: launch_all_nukes simulation_number: 2
...
$: launch_all_nukes simulation_number: 3
...
これらは平均で25分かかるにもかかわらず、それは時々時間のように感じています。画面を見つめ...$: launch_all_nukes simulation_number: 4
。ちょうど別の通常の日。もう...定期的な...日...
$: launch_all_nukes simulation_number: 5
...
ティック-TOK、TIK-TOK、TIK-TOK ...昼食のためにそこにあるかもしれないか疑問に思いますか?最後に$: launch_all_nukes simulation_number: 6
...
! 7は常に最も興味深いものです。唯一消滅しない可能性があるのは、0.03%〜0.08%の確率であることが時々分かります。アイバンは7号の背後に何があるのか全く分かりません。他のシミュレーションもそうです。彼はちょうどコマンドを実行し、待っている。しかし、確かに、数字7は、そうでなければ鈍い課題で喜びと興奮の小さな梁をもたらすものです。 Aaaaaaand、go!$: launch_all_nukes simulation_number: 7
...
0%。他のすべてのものとして。どのように定期的に。$: launch_all_nukes simulation_number: 8
...
は実際に、それを重要ですか?なぜ、ある国が他の国より優れているのだろうか?人生はそれだけで価値がありますか?地球は本質的に貴重なものですか?無限の宇宙に浮かぶ岩のほんの光景...$: launch_all_nukes simulation_number: 9
...
何が起こったのか?イワンはかつて偉大な開発者だった。そして今、彼は時々、繰り返しコマンドを実行し、コンソールを凝視...進歩のような感じ何本です...$: launch_all_nukes simulation_number: 10
...
は何ですか...ちょっと待ってデフォルト値はsimulation_number:
?それは何ですか?確かに実装には__actually_launch_nukes__ if simulation_number.nil?
のようなチェックがあります。しかし、それは本当にnil
ですか?それとも別のことですか? ...$: launch_all_nukes simulation_number: 11
...
繰り返しイヤーワームと同様に 、この小さな問題は、それが何であるか... を彼の心を残したことはありませんか? ...引数がないlaunch_all_nukes
を実行すると3つの異なるアクセスキーが要求され、そのうちのどれも知っていないことがわかったので、彼は誤って世界を危険にさらすことを恐れなかった。$: launch_all_nukes simulation_number: 12
...
イワンは、通常のRubyは前にコンソールでコマンドを実行しています。是非とも、それは単なる普通のイブです...単純なイントロスペクションメソッドを1つ実行しています...彼はそれができないことを知っています...しかし誰も知りませんよね?誰でもこのプログラムは、とにかくどのように動作するか...ああ...$: launch_all_nukes simulation_number: 13
...
13と14は最悪です!知りません13時間は通常1時間半かかります。 14はさらに長い。やっぱり、イワンは、少なくとも数分は彼の心を握るためにちょっとした情報を欲しがっています。$: method(:launch_all_nukes).default_value_for(:simulation_number)
...
突然の実現が彼を襲ったとして恥ずかしい、イワンは動か凍結しました。彼は今、デフォルト値が何であるか知っています。しかし、それは遅すぎる...ここで
貧乏人の試みです:
argument_name = 'arg2'
origin_file, definition_line = MyClass.instance_method(:index).source_location
method_signature = IO.readlines(origin_file)[definition_line.pred]
eval(method_signature.match(/#{argument_name}\s*[=:]\s*\K[^\s),]*/)[0]) # => "hello"
明らかに非常にエラーが発生しやすい:
)
または,
など)は処理されませんが、これを改善できます。誰かが純粋に内省的解決策を付属している場合、それで行きます。
メソッドの引数の値を検査できるのは、メソッドのbinding
にアクセスすることだけです。 Tracepoint
クラスを使用すると、このようなバインディングオブジェクトを取得し、すべてのoptional
パラメータの値を検査できます。
デフォルトのパラメータにデフォルト値が割り当てられるように、必要なパラメータだけを指定してメソッドを呼び出す必要があります。
これは私の試みです。インスタンスメソッドとクラスメソッドの両方で動作します。インスタンスメソッドを呼び出すには、クラスをインスタンス化する必要があります。コンストラクタにパラメータが必要な場合は、オブジェクトを作成するのが難しくなります。この問題を回避するために、このコードでは、指定されたクラスのサブクラスを動的に作成し、それに対して引数なしのコンストラクタを定義しています。
class MyClass
# one arg constructor to make life complex
def initialize param
end
def index(arg1, arg2="hello", arg3 = 1, arg4 = {a:1}, arg5 = [1,2,3])
raise "Hi" # for testing purpose
end
def self.hi(arg6, arg7="default param")
end
end
def opt_values(clazz, meth)
captured_binding = nil
TracePoint.new(:call) do |tp|
captured_binding = tp.binding
end.enable {
# Dummy sub-class so that we can create instances with no-arg constructor
obj = Class.new(clazz) do
def initialize
end
end.new
# Check if it's a class method
meth_obj = clazz.method(meth) rescue nil
# If not, may be an instance method.
meth_obj = obj.method(meth) rescue nil if not meth_obj
if meth_obj
params = meth_obj.parameters
optional_params = params.collect {|i| i.last if i.first == :opt}.compact
dummy_required_params = [""] * (params.size - optional_params.size)
# Invoke the method, and handle any errors raise
meth_obj.call *dummy_required_params rescue nil
# Create a hash for storing optional argument name and its default value
optional_params.each_with_object({}) do |i, hash|
hash[i] = captured_binding.local_variable_get(i)
end
end
}
end
p opt_values MyClass, :index
#=> {:arg2=>"hello", :arg3=>1, :arg4=>{:a=>1}, :arg5=>[1, 2, 3]}
p opt_values MyClass, :hi
#=> {:arg7=>"default param"}
なぜ好きではないのですか? – jeffdill2
この質問の会話には、次のようないくつかのオプションがあります。http://stackoverflow.com/questions/622324/getting-argument-names-in-ruby-reflection –
もう1つです:http://stackoverflow.com/questions/2452077 /ルーのメソッド名パラメータ名へ戻る –