Rubyのブロック機能をより深く理解するために
ブロックとは何ですか?
Rubyでは、ブロックは珍しいものではありません。ブロックの正式な定義は "ラップされたコードの一部" です。もちろん、この説明でわかりやすくなるとは思えませんが。
ブロックのもっと簡単な説明は "ブロックは変数に格納されたコードの一部であり、他のオブジェクトと同様にいつでも実行できます"。
では、いくつかのコードを見て、そのコードをRubyのブロック形式に再構築してみましょう。実際にコードを見て感じた方が直感的にわかると思います。
例えば、2つの数字を足すと?
puts 5 + 6
# => 11
まあ、そういう書き方でもいいんですけどね。しかし、このコードはブロック定義の前半部分しかやっていないのです。しかし、quot;wrap"やquot;stored in a variable"はしていないのです。
だから、どんどん修正していく必要があるんです。しかし、それをまとめる前に、より一般的な外観になるように改良してみましょう。
a = 5
b = 6
puts a + b
# => 11
OK ~ これは動作します - 前の数値を変数に置き換えたのです。このコードは合計処理を実行しますが、しかし、まだ変数に格納されていません。
では、実装してみましょう。
addition = lambda { |a, b| return a+b }
puts addition.call(5, 6)
# => 11
これで、きれいにまとまりましたね。
Rubyでブロックを作るには、「lambda」キーワードを使うのが最も一般的な方法です。他にも方法はありますが、今は無視してください。
この時点であなたはおそらく、「待てよ、これはクラスとオブジェクトがないことを除けば、メソッドのように見えるぞ」と思っていることでしょう。その通りです。ブロックはメソッドに似ていますが、オブジェクトと関連付けられていないのです。
では、ブロックについて詳しく見ていきましょう。
ブロックはコードのブロックを含みます。ブロックには名前を付けることができます。ブロック内のコードは、常に中括弧({})またはdo... ...endで囲まれています。
[1, 2, 3].each do |i|
puts i
end
#=> 1
2
3
上記の例では、各メソッドの後にdo...end構造が続いており、これがブロックです。
Rubyでは、どのようなメソッドにもブロックを渡すことができます。
def test;end
test{ puts i}
def test
yield
end
test{puts "hello test!"}
def test(x)
yield(x)
end
test('world!'){|x| puts "hello #{x}"}
yieldキーワードは、コードのブロックをマウントするだけでなく、ブロックに引数を渡すこともできます。
def test(&block)
block.call("world")
end
test{|msg| puts "hello #{msg}"}
The block goes inside the method and has been & transformed into a Proc object.
def test(&block)
inner_test(&block)
end
def inner_test
yield("haha! ")
end
test{|msg| puts "hello #{msg}"}
testメソッドで渡されたブロックはProcオブジェクトに変換され、その中のinner_testはこのProcオブジェクトを"&"でブロックに変換しています。
ブロックはオブジェクトなのか?もちろん、Rubyの他のすべてのものと同じように、ブロックはオブジェクトです。
empty_block = lambda { }
puts empty_block.object_id
# => 28765760
puts empty_block.class
# => Proc
puts empty_block.class.superclass
# => Object
このように、作成したブロックは object_id を持ち、これは Proc クラス (Ruby ではブロックと呼びます) に属し、それ自体が Object のサブクラスになっています。
この逆で、ブロックからメソッドを定義することもできます。メソッドとは、オブジェクトにバインドされたブロックのことで、オブジェクトの "state"にアクセスすることができます。
前の問題を実装するために、より伝統的な方法があります(そして、私の貧弱なオブジェクトのモデリングを許してください)。
class Calculator
def add(a, b)
return a+b
end
end
puts Calculator.new.add(5, 6)
# => 11
このコードは確かにうまく動きます。では、ちょっとだけ改造してみましょう。
class Calculator
def add(a, b)
return a+b
end
end
addition_method = Calculator.new.method("add")
addition = addition_method.to_proc
puts addition.call(5, 6)
# => 11
これで、伝統的な手法をブロックに変換したことになりますね
コードをブロック化しよう
足し算、引き算、掛け算、割り算をする4つのブロックを作ってみましょう。各ブロックは2つの値を変数として受け取り、演算を実行して結果を返します。
Addition = lambda { |a, b| return a+b }
Subtraction = lambda { |a, b| return a-b }
Multiplication = lambda { |a, b| return a*b }
Division = lambda { |a, b| return a/b }
# Use by call when using
Addition.call(5, 6)
# => 11
関連
-
Ruby正規表現とサンプルコード
-
Rubyの文法と言語機能のまとめ
-
アプレットを置き換えるHTMLスクリプトを記述するRubyの例
-
Rubyのオブジェクト指向のアプローチによるプログラミング学習雑学
-
Ruby は REXML ライブラリを使って xml 形式のデータをパースする
-
RubyアプリケーションでHTTPベースのリクエストを送信する簡単な例
-
デザインパターンのうち、ProxyパターンとDecorativeパターンを使ったRubyのコード例
-
Rubyの4つの比較関数(equal?, eql?, ==, ===)について解説します。
-
Rubyのプライベートとプロテクトを簡単にご紹介します。
-
Rubyの基本構文
最新
-
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 実装 サイバーパンク風ボタン