This works:
class MyAwesomeClass
variable_of_doom = ["things", "stuff", "chunky_bacon"]
variable_of_doom.each do |name|
define_method("#{name}") do
puts name
end
end
end
puts (MyAwesomeClass.instance_methods - Object.instance_methods).inspect
# => ["things", "stuff", "chunky_bacon"]
这不,但这就是我需要的:
variable_of_doom = ["things", "stuff", "chunky_bacon"]
class MyAwesomeClass
variable_of_doom.each do |name|
define_method("#{name}") do
puts name
end
end
end
puts (MyAwesomeClass.instance_methods - Object.instance_methods).inspect
# => NameError: undefined local variable or method ‘variable_of_doom’ for MyAwesomeClass:Class
# => method <class:MyAwesomeClass> in untitled 4 at line 9
# => method <main> in untitled 4 at line 7
答案 0 :(得分:2)
你的问题归结为这个失败的例子:
variable_of_doom = %w(famine plague flood war pestilence drought television)
class MyAwesomeClass
# undefined local variable or method `variable_of_doom' for MyAwesomeClass:Class
puts variable_of_doom
end
厄运变量是否恒定?如果是这样,以下工作,因为类可以访问在它们自己的类定义之外声明的常量:
VARIABLE_OF_DOOM = %w(famine plague flood war pestilence drought dos)
class MyAwesomeClass
puts VARIABLE_OF_DOOM
end
如果你需要值得注定的变量是动态的,你可以用一个知道如何传递它们的方法来创建一个模块或类。
module VarsOfDoom
VOD = %w(famine plague flood war pestilence drought computer-mouse)
def self.dynamic
VOD.shuffle
end
end
class MyAwesomeClass
# Works because the module VarsOfDoom is itself a constant.
puts VarsOfDoom::VOD
puts
puts VarsOfDoom.dynamic
end
我不会诉诸于$variables_of_doom
全球化。这没有必要,原则上应该避免。
答案 1 :(得分:1)
在Ruby中,class
(或def
)块划分了一个新的独立范围,在该范围内无法访问来自周围范围的局部变量。如果您需要将周围的局部变量放在范围内,您可以使用块来解决这个问题,例如:
variable_of_doom = ["things", "stuff", "chunky_bacon"]
MyAwesomeClass.class_eval do
variable_of_doom.each do |var|
# do whatever you need here
end
end
在Pragmatic Bookshelf的 Ruby Metaprogramming 中,他们描述了将此技术用作“范围门”:当您想要创建新范围时,使用class
或def
块对于局部变量,请在不使用时使用块。
答案 2 :(得分:0)
在Ruby中,全局变量需要由$
表示,就像实例变量用@
表示一样。所以这有效:
$variable_of_doom = ["things", "stuff", "chunky_bacon"]
class MyAwesomeClass
$variable_of_doom.each do |name|
define_method("#{name}") do
puts name
end
end
end
puts (MyAwesomeClass.instance_methods - Object.instance_methods).inspect
# => [:things, :stuff, :chunky_bacon]
答案 3 :(得分:0)
如何解决问题已在其他答案中说明。我建议你按照下面这样的instropection
检查范围规则:
variable_of_doom = ["things", "stuff", "chunky_bacon"]
defined? variable_of_doom # => "local-variable"
local_variables.include? :variable_of_doom # => true
class MyAwesomeClass
p defined?(variable_of_doom)
p local_variables.include?(:variable_of_doom )
end
# >> nil
# >> false
答案 4 :(得分:0)
创建全局变量并不是一个好主意,相反,将variable_of_doom移动到Class范围将是一个神明的想法。