我有一个名为Foo
的引擎的初始化程序,如下所示:
# config/initializer/foo.rb
class Foo::Engine < ::Rails::Engine
config.bar = 'baz'
end
但它表现得出乎意料:
Foo::Engine.config.bar # => 'baz' # expected
defined?(Foo::Engine.config.bar) # => nil, why?
为什么defined?
为零?
此外,当我Foo::Engine.config.inspect
出现很多事情但bar
无处可寻。为什么呢?
答案 0 :(得分:1)
如Expressions @ Programming Ruby中所述,
defined?
运算符如果未定义其参数(可以是任意表达式),则返回nil
,否则返回该参数的描述。
defined? 1 → "expression"
defined? dummy → nil
defined? printf → "method"
defined? String → "constant"
defined? $& → nil
defined? $_ → "global-variable"
defined? Math::PI → "constant"
defined? ( c,d = 1,2 ) → "assignment"
defined? 42.abs → "method"
所以对于课程:
ruby-1.9.2-p180 > defined? Person
=> nil
ruby-1.9.2-p180 > class Person
ruby-1.9.2-p180 ?> end
=> nil
ruby-1.9.2-p180 > defined? Person
=> "constant"
方法:
ruby-1.9.2-p180 > def cool
ruby-1.9.2-p180 ?> puts "clear"
ruby-1.9.2-p180 ?> end
=> nil
ruby-1.9.2-p180 > defined? cool
=> "method"
在你的情况下,
defined?(options)
正在调用options方法并将结果传递给defined?
。
感谢@Stuart,提到它不是一个真正的方法,但它由method_missing实现,这里有一点魔力。
所以实际上你不应该期望定义方法选项,因此baz
得到nil。
答案 1 :(得分:1)
这是因为#bar
不是Rails::Engine::config
上的真实方法,而是通过Rails::Railtie::Configuration
中的#method_missing
实现的。如果它是一个真实的方法(使用def bar
实施)defined?
将返回"method"
。
class Foo
def bar
'bar'
end
def method_missing(name, *args, &blk)
if name == :baz
'baz'
end
end
end
f = Foo.new
f.bar # => "bar"
defined?(f.bar) # => "method"
f.baz # => "baz"
defined?(f.baz) # => nil
为了解决问题的第二部分,#inspect
不包括bar
,因为配置选项存储在@@options
类变量中,而不是存储在实例变量{}中{1}}通常看起来:
#inspect