6

我收到此错误:MyModule.rb:4:in getName': undefined local variable or methods' for MyModule:Module (NameError)

文件 1

module MyModule
  s = "some name"
  def self.getName()
    puts s
  end 
end

文件2

require './MyModule.rb'

include MyModule
MyModule.getName()

这与范围有关,但如果我在方法之前声明它,我不理解为什么会发生这种情况。只包括 mixin 方法而不包括变量?如何更改我的模块,以便它可以打印出我在模块中定义的变量?

4

1 回答 1

29

这与范围有关,但我不明白为什么会这样

Adef创建一个新范围。在某些语言中,内部作用域可以看到周围作用域中的局部变量——但在 ruby​​ 中则不行。您可以改用常量:

module MyModule
  S = "some name"

  def getName()
    puts S
  end 
end

include MyModule

getName

--output:--
some name

但是可以从任何地方访问常量:

module MyModule
  S = "some name"

  def getName()
    puts S
    puts Dog::S
  end 
end

module Dog
  S = "hello"
end

include MyModule

getName

--output:--
some name
hello

更高级的解决方案涉及使用闭包。与 a 不同def,块可以看到周围范围内的局部变量,这称为关闭变量。这是一个例子:

module MyModule
  s = "some name"
  define_method(:getName) { puts s }
end

include MyModule

getName

--output:--
some name

使用闭包的好处是只有块才能访问s.

只包括 mixin 方法而不包括变量?

这取决于变量的类型:

module MyModule
  A = 'hello'
  s = 'goodbye'
end

include MyModule

puts A
puts s

--output:--
hello

1.rb:9:in `<main>': undefined local variable or method `s' for main:Object (NameError)

module关键字 like会创建一个新def范围。你知道当方法执行完成时局部变量是如何被销毁的吗?当一个模块完成执行时,它的局部变量也会被销毁:

module MyModule
  puts "MyModule is executing"
  s = 'goodbye'
end

include MyModule

puts s

--output:--
MyModule is executing

1.rb:7:in `<main>': undefined local variable or method `s' for main:Object (NameError)
于 2013-08-22T07:58:41.367 回答