2016-06-21 2 views
-2

私は最近、多くのルビメソッドで使用されているパイプ入力がある程度必要ではないことを発見しましたが、これは矛盾しているようです。あなたがそこにはパイプで連結された入力されていない、との機能は、単にメソッドがコールされていることを前提とし、instance_evalを内部に見ることができるようにRubyでパイプ入力が必要なのはいつですか? (| x | x.to_s)

DateTime.now.instance_eval{[prev_day, to_datetime, tomorrow]}.map{|d| d.strftime('%m/%d/%Y')} 
=> ["06/20/2016", "06/21/2016", "06/22/2016"] 

:たとえば、この行は、昨日、今日、そして明日のための文字列の配列を作成し、 DateTime.now。しかし、同じ方法をマップメソッドに適用しようとすると、

DateTime.now.instance_eval{[prev_day, to_datetime, tomorrow]}.map{strftime('%m/%d/%Y')} 
NoMethodError: undefined method `strftime' for main:Object 

突然、メインでメソッドを使用しようとしていますか?

私の質問は、なぜこの方法が第1の方法ではなく、第2の方法で機能するのかということです。 docs for instance_evalから

答えて

1

:あなたはインスタンスにそれを呼び出すと、それが明示的インスタンスのコンテキストでブロックを実行するために構築されたため、一方で

Evaluates a string containing Ruby source code, or the given block, within the context of the receiver (obj). In order to set the context, the variable self is set to obj while the code is executing, giving the code access to obj's instance variables and private methods.

instance_evalは、非常に特別です。したがって、この方法では、常にselfのコンテキストが常にinstance_evalが呼び出されたインスタンスであると想定できます。一方、

mapは異なっている:あなたの例では、配列にそれを呼び出すが、ブロックが配列内上の各オブジェクトを実行する必要があり、したがって、あなたは、それぞれのブロックに異なるオブジェクトを渡す必要があります繰り返し。ブロックは、引数を有するyieldと任意のメソッドに渡されたとき

+0

Ah ha!私のコードに戻ると、これは常に動作しているinstance_evalです。 OK、今は意味をなさない。 – oMiKeY

+0

これは実際には 'instance_eval'とはまったく関係ありません。もっと単純な例は '[1,2,3] .map {chr}'と '[1,2,3] .map {| x | x.chr} 'となります。結果はまったく同じです。 –

+0

@Mike:あなたの例を再現できません: '[1,2,3] .map {chr}'の結果は ですNameError:未定義のローカル変数またはメソッド 'chr' for main:Object' on Ruby 2.3.1 – spickermann

0

When are piped inputs necessary in Ruby? (|x| x.to_s)

パイプによる入力が必要です。

instance_evalの収量には引数がありませんが、mapの場合は収量がありません。あなたが持っている問題はinstance_evalとは関係ありません。 yieldが変数を渡すことを期待していますが、そうしないと、selfが主オブジェクトであると想定されます。そして、それは正確にはmapで2番目の例で起こっていることです。この例を見てください。

def yield_to_integer # yield integer 5 to the block 
    yield 5 
end 

yield_to_integer {|int| int.chr} # successfully run .chr() on the Integer 5 
# => "\x05" 
yield_to_integer {chr} # fails to run .chr() because it is not defined on Object 
# NameError: undefined local variable or method `chr' for main:Object 
関連する問題