Photo by Jack Anstey on Unsplash

An overview of execution context of blocks

Mehdi Farsi

Follow

Sep 20, 2019 – 3 min read

この記事では、以下のトピックについて掘り下げていきます。

  • スコープとブロック
  • クラス/モジュールのフラットスコープガード

まず、Rubyのスコープゲートを自由に閲覧してください。 Part II の記事

始める前に

私たちの最新のプロジェクトを紹介することに興奮しています。 Ruby の基礎知識 – 第1巻

ぜひこのリンクをシェアして、広めてください。 🙏

ありがとうございました!

Rubyでは、ブロックは外部スコープにアクセスできます

この例では、ブロック内で変数 outer_scope_variable にアクセスすることが可能です。 この変数はmainレベルのスコープで宣言されているにもかかわらず、我々のブロックはこの変数にアクセスすることができる。 この場合、ブロックはスコープを平らにしていると言います。 このため、この機構を一般にこう呼びます。 フラット スコープ.

一方、ブロックは孤立したスコープを作成します – ブロック内の self の値が main オブジェクトのままでもです。

したがって、ブロック内で定義されたローカル変数にアクセスできません

ここで、外部スコープから block_variable にアクセスできないのはそのためです。 Ruby のフラットスコープの概念に慣れてきたので、この概念がクラス定義に影響を与えるかどうかを見てみましょう。

クラス、モジュール、ブロック

Rubyでは、一般にクラスと呼ばれるものは、裏ではClassクラスのインスタンス

ここで、HelloGreetingクラスを2種類の方法で作っています。

  • classキーワードを使う
  • 定数GreetingClassクラスのインスタンスを代入する

なお、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 にアクセスできるのです

ボイラ!

Articles

コメントを残す

メールアドレスが公開されることはありません。