ホーム DoRuby 【Ruby】変数やクラス定義などのスコープ
 

【Ruby】変数やクラス定義などのスコープ

この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。

制御構文ではスコープを作らない(if, while、forなど)

Rubyではifやwhile、forなどの制御構文ではスコープを作りません。

if true
  hoge = 'abcd'
end
p hoge #=> abcd

for i in 0..5 do
  i += 1
end
p i #=> 6

# if, for内で定義された変数は抜けた後も有効

ブロックはスコープを作る(each, map, timesなど)

each, map, timesなどブロックを引数にとるメソッドでは
ブロック内でスコープが作られます。

[0,1,2].each do |i|
  total ||= 0
  total += i
end
p total
NameError: undefined local variable or method `total' for main:Object
        from (irb):2
        from /home/hoge/.rbenv/versions/2.1.8/bin/irb:11:in `<main>'

ブロック内で定義された変数totalには
外部からアクセスできません。

ブロック外で定義した変数はブロック内でも有効です。

total=10
[0,1,2].each do |i|
  total ||= 0
  total += i
end
p total  #=> 13

 
制御構文もdo~endがあってブロックのように見えますが、
ブロックではないそうです(要調査)
 

module, class, defもスコープを作る

module, class, defもスコープを作りますが、少し違います。
この場合は外部<=>内部のアクセスはどちらもできません。

num=10
def fuga
  num ||= 99
end
p num   #=> 10
p fuga  #=> 99

フラットスコープ

同じクラス/メソッド定義でも、class,defを使うとスコープが作られて、
Class.newやdefine_methodを使うと作られない、などもあります。

▼classで定義した場合は外側で定義したxにアクセスできない

x = 'XX'
class Hoge
  def method_x
    x
  end
end
Hoge.new.method_x
NameError: undefined local variable or method `x' for #<Hoge:0x007fe556dbc200>
        from (irb):4:in `method_x'
        from (irb):7
        from /home/hoge/.rbenv/versions/2.1.8/bin/irb:11:in `<main>'

▼Class.newやdefine_methodを使うと外側の変数にアクセスできる

x = 'XX'
y = 'YY'
Hoge = Class.new() do
  p y  #=> 'YY'
  define_method(:method_x) do
    x
  end
end
Hoge.new.method_x  #=> 'XX'

これをフラットスコープといいます。

 
 
 
「メタプログラミングRuby」に詳しく記載があるので
とてもおすすめです。
スコープについての記載がとても興味深かったので、
もう少し読み解いて理解を深めたいと思います。

記事を共有
モバイルバージョンを終了