LoginSignup
1
1

More than 5 years have passed since last update.

メタプログラミングRuby 4章 スコープを越える スコープゲート フラットスコープ その1

Last updated at Posted at 2017-10-10

メタプログラミングRuby 4章のブロックに関してのアウトプット。

変数のscopeを越える方法(スコープゲートの突破)をまとめます。

Before

scope.rb
var = "scopeを越える瞬間!!"
puts var #=> scopeを越える瞬間!!

class HogeClass# スコープの壁①

  puts "①ここで使えるようにしたい"
  puts var #=> error

  def magic_scope# スコープの壁②
      puts "②メソッドの中でも使いたい"
      puts var
  end
end

実行すると....

$ ruby scope.rb 

scopeを越える瞬間
ここで使えるようにしたい
scope.rb:11:in `<class:HogeClass>': undefined local variable or method `var' for HogeClass:Class (NameError)
Did you mean?  var
    from scope.rb:8:in `<main>'

→ 普通にscopeで落ちる。

これを使えるようにしてしまうのが、スコープのフラット化 というものです。

After

まずは①のスコープゲートを超える方法。
classをスコープゲートではない、メソッド呼び出しに置き換える。メソッド呼び出し。
→ブロックをClass.newに渡すと、クラスにインスタンスメソッドを定義することができます。

scope.rb
var = "scopeを越える瞬間"
puts var

HogeClass = Class.new do # ブロックをClass.newに渡す

  puts "ここで使えるようにしたい"
  puts "①:#{var}" # ①

  def magic_scope
      puts "メソッドの中でも使いたい"
      puts "②:#{var}" # ②
  end
end

実行

$ ruby scope.rb
scopeを越える瞬間
ここで使えるようにしたい
①:scopeを越える瞬間 #=> 超えた!!

続いて②を超えます。

ここもメソッド呼び出しに置き換えることで実現可能。
define_methodを使用する。

scope.rb

var = "scopeを越える瞬間"
puts var

HogeClass = Class.new do

 puts "ここで使えるようにしたい"
 puts "①:#{var}"

 define_method(:magic_scope) do
   puts "メソッドの中でも使いたい"
   puts "②:#{var}"
 end
end

puts HogeClass.new.magic_scope

実行

$ ruby scope.rb
scopeを越える瞬間
ここで使えるようにしたい
①:scopeを越える瞬間
メソッドの中でも使いたい
②:scopeを越える瞬間

以上です。
フラットスコープを駆使すれば、スコープでやりたいことはほとんどできそうです
個人開発の時にはどんどん使用してみます。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1