0

私は現在ブロックを検討していますが、それらは私を困惑させました。

これを例として使用しました:

class ProcExample
  attr_reader :proc_class
  def initialize(&block)
    @stored_proc = block
    @proc_class = @stored_proc.class
  end
  def use_proc(arg)
    @stored_proc.call(arg)
  end
end

eg = ProcExample.new {|t| puts t}
p eg.proc_class
p eg.use_proc("Whoooooooo")

ブロックが @stored_proc にどのように渡されるかを理解できませんでした。@proc_class を使用したのは、ブロック オブジェクトが実際にどのクラスとして格納されているのか知りたかったからです。

しかし、ブロックを通常の変数に格納したい場合はどうすればよいでしょうか?

例えば:

block_object = {|param| puts param**2}

しかし、これはブロック/プロシージャではなくハッシュとして扱われることがわかりました。当然誤差が出ます。変数名とブロックの先頭にアンパサンドを付けて割り当てようとしましたが、うまくいきません。

最終的に、関数を呼び出してブロックをブロックを含む変数に置き換えることができるかどうか疑問に思っていました。

そのようです:

(1..10).each block_object

これはRubyで可能ですか?

4

3 に答える 3

4

ブロックを変数に割り当てることはできません。

ブロックは実際にはオブジェクトではありません。これらは、コードを高次のメソッドに渡すための特別な構文です。変数に割り当て、受け渡し、操作できる実行可能コードが必要な場合は、Procオブジェクトを使用する必要があります。

Procs には、ラムダと通常の proc の2 種類があります。これらは、引数バインディングのセマンティクスとセマンティクスという 2 つの側面で異なる動作をしますreturn。ラムダは、メソッドのように引数をバインドし、メソッドからメソッドが返されるreturnように、ラムダから返されます。return通常のプロシージャは、ブロックのように引数をバインドし、ブロックreturnのように、プロシージャではなく、囲んでいるメソッドから戻りますreturn

Proc.new通常のプロシージャは、ブロックを に渡すか、代わりに に渡すことで作成できますKernel#proc。ラムダは、ブロックを渡すKernel#lambdaか、「安定したラムダ」リテラル構文を使用して作成できます。

lambda_object = ->param { puts param**2 }

Procs をブロックに、またはその逆に変換するために、Ruby には単項接頭辞&修飾子があります。この修飾子は、パラメーター リストと引数リストでのみ有効です。パラメーターリストで使用すると、「ブロックを proc でラップし、この変数にバインドする」ことを意味します。引数リストで使用する場合。これは、「この proc をブロックにアンラップし (まだ proc でない場合は、to_proc最初に呼び出して)、ブロック引数として渡す」ことを意味します。

(1..10).each(&lambda_object)

単項接頭辞修飾子がこのように使用されているのを見たことがないことに驚いています。&実際にはかなり一般的です['1', '2'].map(&:to_s)

実行可能コードを表すもう 1 つのMethod種類のオブジェクトは、オブジェクトです。sと同じインターフェイスの一部、特に 、 、Procなど#call#to_procサポートしています。オブジェクトを取得するには 2 つの方法があります。メソッドを使用してそのレシーバーからレシーバーにバインドされているメソッドを取得するか、クラスからオブジェクトを取得します。またはモジュール (例: using ) を使用して、オブジェクトを返すレシーバーにバインドします。#arguments#arityMethodObject#methodUnboundMethodModule#instance_methodUnboundMethod#bindMethod

Methodが実装されているため、単項接頭辞修飾子to_procを使用してブロックとしてメソッドに渡すことができます。&

# Warning: extremely silly example :-)

ary = []

(1..10).each(&ary.method(:<<))

ary
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

ary = []

(1..10).each(&Array.instance_method(:<<).bind(ary))

ary
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
于 2013-05-12T01:47:28.130 に答える
2

あなたは proc オブジェクトを探していると思います。

block = proc { ... }
于 2013-05-11T23:30:28.383 に答える
1

proc またはラムダを使用できます。それらの間にはいくつかの微妙な違いがあります。およびRubyバージョン間。良い概要はここで見ることができます: https://www.youtube.com/watch?v=VBC-G6hahWA Peter Cooper 提供

于 2013-05-11T23:46:47.680 に答える