Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
330 views
in Technique[技术] by (71.8m points)

Ruby local variable is undefined

I have the following Ruby code:

local_var = "Hello"

def hello
  puts local_var
end

hello

I get the following error:

local_variables.rb:4:in 'hello': undefined local variable or method 'local_var' 
for main:Object (NameError) from local_variables.rb:7:in '<main>'

I always thought that local variables are not accessible from outside of the block, function, closure, etc.

But now I defined local variable in the file and try to get an access from the function INSIDE the same file.

What's wrong with my understanding?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In Ruby local variables only accessible in the scope that they are defined. Whenever you enter/leave a Class, a Module or a Method definiton your scope changes in Ruby.

For instance :

v1 = 1

class MyClass # SCOPE GATE: entering class
  v2 = 2
  local_variables # => ["v2"]

  def my_method # SCOPE GATE: entering def
    v3 = 3
    local_variables  # => ["v3"]
  end # SCOPE GATE: leaving def

  local_variables # => ["v2"]
end # SCOPE GATE: leaving class

These entering and leaving points are called Scope Gates. Since you enter through Scope Gate via method definition you cannot access your local_var inside hello method.


You can use Scope Flattening concept the pass your variable through these gates.

For instance instead of using def for defining your method you can use Module#define_method.

local_var = "Hello"

define_method :hello do
  puts local_var
end

In the same way you can define your classes via Class#New so that your scope does not change when you pass through class definition.

local_var = 'test'

MyClass = Class.new do
  puts local_var #valid
end

instead of

class MyClass
  puts local_var #invalid
end

In the same way you should use Module#New if you want to pass your local variables through Module gates.

Example is taken from Metaprogramming Ruby


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...