rails Foo :: Engine.config.something没有定义?

时间:2013-03-05 08:08:18

标签: ruby-on-rails ruby ruby-on-rails-3

我有一个名为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无处可寻。为什么呢?

2 个答案:

答案 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