0

この質問にタイトルを付ける方法を本当に知りませんでした。

任意のハッシュを考えてみましょう(ENVが便利です):

ENV.each { |key, val| puts key + ': ' + val }
LC_MESSAGES: en_US.utf-8
LC_COLLATE: en_US.utf-8
PWD: /Users/baller/ive_fallen_and_i_cant_get_up
LC_MONETARY: en_US.utf-8

&:省略形を使用してこれを行うことは可能ですか?

foo.each(&:bar)
4

4 に答える 4

1

デフォルトでは、いいえ。

必要なことを行うには、Arrayクラスにメソッドを追加する必要があります。このメソッドは、次のように希望どおりに出力します。

class Array
  def bar
    puts "#{self[0]}: #{self[1]}"
  end
end

それで、ENV.each(&:bar)あなたが期待することをします。

そうは言っても、私はこれをお勧めしません。基本クラスへの追加は、ユーティリティが将来の競合の可能性をはるかに上回っている場合にのみ実行する必要があります。このメソッドは、少なくとも2つの要素を含む配列に高度に特化しています。

関連はありませんが、を介した文字列の連結+は、補間を使用するよりもかなり遅くなります。不必要に余分なオブジェクトを作成します。

于 2012-10-02T00:36:42.230 に答える
1

あなたの例で&:barは、ブロックの代わりに使用する#to_procと、指定されたオブジェクト(この場合はシンボル)で呼び出されます:bar。RubyでのSymbolの#to_proc実装は、基本的にに拡張foo.each(&:bar)されfoo.each { |i| i.bar }ます。ハッシュから生成される引数は2つあるためi、この例では、キーの配列であるvalueargsを使用します。これがArray、ハッシュを期待どおりに処理するために(@ x1a4で説明されているように)拡張する必要がある理由です。

別の方法として、ブロックに応答する#to_procか、単にブロックをProcとして実装する独自のクラスを作成できます。

class Bar
  def to_proc
    Proc.new { |key, val| puts key + ': ' + val }
  end
end

bar = Bar.new

# or

bar = Proc.new { |key, val| puts key + ': ' + val }

バーへのハンドルを使用すると、ブロックの代わりに&barをENVのようなハッシュに渡すことができます。したがって、ハッシュを指定すると、foo:

foo.each(&bar)

このテーマに関する詳細を読むための素晴らしい投稿:http ://weblog.raganwald.com/2008/06/what-does-do-when-used-as-unary.html

于 2012-10-02T00:58:49.520 に答える
1

一般に、これは、コレクションの要素がそのメソッドに応答する場合に可能です。例えば:

class Foo
  attr_reader :bar

  def initialize(bar)
    @bar = bar
  end
end

foos = [Foo.new("one"), Foo.new("two"), Foo.new("three")]

p foos.map(&:bar)  #=> ["one", "two", "three"]

これ&symbolは、のシンタックスシュガーでsymbol.to_procあるため機能します。これは、引数として受信したオブジェクトにそのメッセージを送信するブロックを返すために何らかの魔法を使用します。

これはあなたの例ではENV機能しませんが(のオブジェクトはに応答しないため:bar)、変数に格納されているブロックを渡すには、次を使用し&ます。

block = lambda { |key, value| puts "#{key}: #{value}" }
ENV.each(&block)
于 2012-10-02T00:59:17.403 に答える
1

これを行うことで、2つのブロック変数を使用せずに、代わりに1つのブロック変数を使用できます。

each{|kv| puts kv.join(": ")}
于 2012-10-02T05:16:17.650 に答える