An overview of execution context of blocks
この記事では、以下のトピックについて掘り下げていきます。
- スコープとブロック
- クラス/モジュールのフラットスコープガード
まず、Rubyのスコープゲートを自由に閲覧してください。 Part II の記事
始める前に
私たちの最新のプロジェクトを紹介することに興奮しています。 Ruby の基礎知識 – 第1巻
ぜひこのリンクをシェアして、広めてください。 🙏
ありがとうございました!
Rubyでは、ブロックは外部スコープにアクセスできます
この例では、ブロック内で変数 outer_scope_variable
にアクセスすることが可能です。 この変数はmain
レベルのスコープで宣言されているにもかかわらず、我々のブロックはこの変数にアクセスすることができる。 この場合、ブロックはスコープを平らにしていると言います。 このため、この機構を一般にこう呼びます。 フラット スコープ.
一方、ブロックは孤立したスコープを作成します – ブロック内の self
の値が main
オブジェクトのままでもです。
したがって、ブロック内で定義されたローカル変数にアクセスできません
ここで、外部スコープから block_variable
にアクセスできないのはそのためです。 Ruby のフラットスコープの概念に慣れてきたので、この概念がクラス定義に影響を与えるかどうかを見てみましょう。
クラス、モジュール、ブロック
Rubyでは、一般にクラスと呼ばれるものは、裏ではClass
クラスのインスタンス
ここで、Hello
とGreeting
クラスを2種類の方法で作っています。
class
キーワードを使う- 定数
Greeting
にClass
クラスのインスタンスを代入する
なお、Class.new
メソッドにブロックを渡していることに注意してください。 このブロックは、クラスの内容として解釈されます。 class
キーワードは self
の値を変更し、孤立したスコープを作成します。
したがって、ブロックを使用して Greeting
クラスを作成しているため、フラット スコープのメカニズムを使用できるはずです。
ここで、class
または Class.new
を使用すると、self
の値が変わることがわかります。
また、def
キーワードを使用しているため、Class#message
ブロックも main
オブジェクトから分離されています。 実際、私たちのブロックはメソッドのコンテキストで実行されるため、ブロックはこの与えられたオブジェクト内でスコープを平らにし、main
オブジェクトのような高いスコープではありません。
それが、message
内で outer_variable
にアクセスできない理由です。
しかし、define_method
を使って message
を定義すると、スコープがフラットになります
ここで define_method(:message)
がブロックを引数に取るので、このブロックのスコープがフラットになり、このメソッドは outer_variable
にアクセスできるのです
ボイラ!