Ruby局部变量未定义 [英] Ruby local variable is undefined

查看:126
本文介绍了Ruby局部变量未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下Ruby代码:

local_var = "Hello"

def hello
  puts local_var
end

hello

我收到以下错误:

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

我一直认为局部变量无法从块,函数,闭包等外部访问.

但是现在我在文件中定义了局部变量,并尝试从功能 INSIDE 获得相同文件的访问权限.

我的理解有什么问题?

解决方案

在Ruby中,局部变量只能在定义的范围内访问.每当您输入/离开类",模块"或方法"定义时,您的范围就会在Ruby中更改.

例如:

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

这些进入点和离开点称为范围门.由于您是通过方法定义通过范围门输入的,因此无法访问hello方法内的local_var.


您可以使用范围展平"概念将变量通过这些门传递.

例如,可以使用Module#define_method代替使用def定义方法.

local_var = "Hello"

define_method :hello do
  puts local_var
end

以相同的方式,您可以通过Class#New定义类,以使在通过类定义时范围不会更改.

local_var = 'test'

MyClass = Class.new do
  puts local_var #valid
end

代替

class MyClass
  puts local_var #invalid
end

如果要通过模块门传递局部变量,则应以相同的方式使用Module#New.

示例摘自元编程Ruby

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?

解决方案

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

这篇关于Ruby局部变量未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆