質問

私は最近、これに似たことをしようとしました:

a = "some string"
b = Proc.new{ upcase }
a.instance_eval b

エラーが発生します:

TypeError:procを文字列に変換できません

しかし、これはうまくいきます:

def b(&block)
  "some string".instance_eval &block
end

b{ upcase }

この方法をさらに見る:

def b(&block)
  "some string".instance_eval block
end

同じものを生成します Proc to String エラー。

だから...ブロックの私の理解は、それらが単なるProcであるということです。しかし、これを持っていることには明らかに特別なことがあります & アンパサンド...

誰かが私にこれを説明できますか?これについて特別なのは、通常のProcを何でも変換することは可能ですか &block 物体?

編集

私の2番目の質問を見つけたばかりで、Prepend An & Procに...それは簡単でしたが、これは本当に何をしていますか?

役に立ちましたか?

解決

最初の例を操作するためにしなければならないのは、これだけです:

>> a.instance_eval &b #=> "SOME STRING"

その理由はそれです instance_eval 文字列またはブロックのいずれかが必要で、アンパサンドは後者を提供します。

ブロックとProcsの違いを理解するために、おそらく次のブログ投稿が役立ちます。

Rubyブロック、Procs、Lambdasの理解

他のヒント

違いはそれです a.instance_eval b 通過しています b instance_evalへの定期的な議論として a.instance_eval &b ブロックとして渡しています。これらは2つの異なるものです。

このメソッド呼び出しを検討してください。

obj.foo(bar) do |x| 
  stuff(x) 
end

それがメソッドを呼び出します foo 1つの通常の議論があります(bar)そして1つのブロック引数(do |x| stuff(x) end)。メソッド定義では、プレフィックスによって区別されます & ブロックパラメーターへ:

def foo(arg, &block)

また、リテラルブロックの代わりに可変式を渡す場合は、同様にプレフィックスによって達成されます & 式(Procを生成するはずです)。

あなたがnoで引数を渡す場合 &, 、それはに行きます arg の代わりにスロット ブロック スロット。議論がたまたまprocのインスタンスであることは関係ありません。構文は、メソッドによってどのように渡され、処理されるかを決定します。

Instance_Evalが評価する文字列またはブロックを受け入れるためです。 instance_eval(&block) あなたを追い越しています block instance_evalへのブロックとして。

重要な違いはそれです Procインスタンスはオブジェクトです 一方 ブロックはオブジェクトではありません. 。 & オペレーターです ブロックとPROCインスタンスを交換します 互いに。

メソッドに対するすべての引数はオブジェクトでなければなりません。引数に加えて、方法はブロックを取ることができます。 instance_eval 文字列引数またはブロックのいずれかを取る方法です。 PROCオブジェクトを渡すと、どちらのケースも満たされません。添付する場合 & PROCオブジェクトには、ブロックとしてヘンゲル化されます。

これは機能します:

a = "some string"
b = Proc.new{ upcase }
a.instance_eval &b

instance_eval メソッドはブロック引数を受信できます。b aです Proc.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top