[解決済み] Rubyのmap(&:method)構文に引数を与えることは可能か?
質問
あなたはおそらく次のようなRubyの省略記法を知っているでしょう (
a
は配列)。
a.map(&:method)
例えば、irbで次のようにしてみてください。
>> a=[:a, 'a', 1, 1.0]
=> [:a, "a", 1, 1.0]
>> a.map(&:class)
=> [Symbol, String, Fixnum, Float]
構文
a.map(&:class)
の省略形です。
a.map {|x| x.class}
.
この構文について詳しくは " をご覧ください。 Rubyでmap(&:name)はどういう意味ですか? "です。
構文を通して
&:class
というメソッド呼び出しを行っています。
class
を配列の各要素に対して行っていることになります。
私の質問は、メソッド呼び出しに引数を供給することができますか?そして、もしそうなら、どのように?
例えば、次の構文をどのように変換するのでしょうか?
a = [1,3,5,7,9]
a.map {|x| x + 2}
を
&:
の構文に変更しますか?
を提案しているわけではありません。
&:
構文が優れていると言っているわけではありません。
私は、単に
&:
の構文を引数で使う仕組みに興味があるだけです。
をご存じだと思いますが
+
は、Integerクラスのメソッドであることはご存知でしょう。 irbで以下を試してみて下さい。
>> a=1
=> 1
>> a+(1)
=> 2
>> a.send(:+, 1)
=> 2
どのように解決するのですか?
簡単なパッチを
Symbol
をこのようにします。
class Symbol
def with(*args, &block)
->(caller, *rest) { caller.send(self, *rest, *args, &block) }
end
end
これだけでなく、どのようなことができるようになるかというと
a = [1,3,5,7,9]
a.map(&:+.with(2))
# => [3, 5, 7, 9, 11]
しかし、複数のパラメータを渡すような、他の多くのクールなものもあります。
arr = ["abc", "babc", "great", "fruit"]
arr.map(&:center.with(20, '*'))
# => ["********abc*********", "********babc********", "*******great********", "*******fruit********"]
arr.map(&:[].with(1, 3))
# => ["bc", "abc", "rea", "rui"]
arr.map(&:[].with(/a(.*)/))
# => ["abc", "abc", "at", nil]
arr.map(&:[].with(/a(.*)/, 1))
# => ["bc", "bc", "t", nil]
そして、さらに
inject
といった、ブロックに2つの引数を渡すものです。
%w(abecd ab cd).inject(&:gsub.with('cde'))
# => "cdeeecde"
あるいは、[shorthand] ブロックを渡すような超クールなもの を を省略記法ブロックに渡すような超クールな方法もあります。
[['0', '1'], ['2', '3']].map(&:map.with(&:to_i))
# => [[0, 1], [2, 3]]
[%w(a b), %w(c d)].map(&:inject.with(&:+))
# => ["ab", "cd"]
[(1..5), (6..10)].map(&:map.with(&:*.with(2)))
# => [[2, 4, 6, 8, 10], [12, 14, 16, 18, 20]]
以下は、私が@ArupRakshitと交わした会話で、さらに詳しく説明しています。
Rubyのmap(&:method)構文に引数を与えることは可能ですか?
で@amcaplanが提案したように
のコメントで提案したように
の名前を変更すれば、より短い構文を作成することができます。
with
メソッドを
call
. この場合、ruby にはこの特別なメソッドのためのショートカットが組み込まれています。
.()
.
ということで、上記をこんな風に使うことができます。
class Symbol
def call(*args, &block)
->(caller, *rest) { caller.send(self, *rest, *args, &block) }
end
end
a = [1,3,5,7,9]
a.map(&:+.(2))
# => [3, 5, 7, 9, 11]
[(1..5), (6..10)].map(&:map.(&:*.(2)))
# => [[2, 4, 6, 8, 10], [12, 14, 16, 18, 20]]
関連
-
[解決済み] ルビー最大整数
-
[解決済み] Rubyでnil値をマッピングして削除する方法
-
[解決済み] Ruby on Railsで現在の絶対URLを取得するにはどうすればよいですか?
-
[解決済み] Rubyのmap(&:name)ってどういう意味?
-
[解決済み] Rubyでindexを使ったマップを作るには?
-
[解決済み] インスタンスメソッドをモンキーパッチする場合、新しい実装からオーバーライドされたメソッドを呼び出すことは可能ですか?
-
[解決済み] Rubyのmapとcollectの違い?
-
[解決済み】Rubyの "map "メソッドは何をするのですか?
-
[解決済み】RubyにあってPythonにないもの、またその逆は何ですか?
-
[解決済み] ruby send メソッドに複数のパラメータを渡す
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Rubyで新しい文字列を作成せずに文字列をトリミングする標準的な方法は何ですか?
-
[解決済み] Ruby プログラムに一定時間待つように指示する
-
[解決済み] RMagickのインストール。MagickWand.hが見当たりません。
-
[解決済み] ルビーです。そのようなファイルやディレクトリはありません @ rb_sysopen - testfile (Errno::ENOENT)
-
[解決済み] 配列をアルファベット順に並べるには?
-
[解決済み] レイルズ・ジェネレート」を逆手に取る方法
-
[解決済み] Ruby で Fixnum から String への暗黙の変換ができない (TypeError)
-
[解決済み] Rubyでfailキーワードは何をするのですか?
-
ERRORの問題を解決します。rails のインストール時に gem ネイティブ拡張のビルドに失敗しました。
-
[解決済み] Rubyのmap(&:name)ってどういう意味?