0

REST API railscast 具有以下代码示例:

module Api
  module V1
    class ProductsController < ApplicationController
      class Product < ::Product
        def as_json(options={})
          super.merge(released_on: released_at.to_date)
        end
      end
    end
  end
end

我无法遵循以下内容:

  class Product < ::Product

...做?当我尝试在 irb 中重新创建类似的东西时,我得到:

module Fooirb(main):001:0> module Foobar
irb(main):002:1> class Product < ::Product
irb(main):003:2> end
irb(main):004:1> end
NameError: uninitialized constant Product
    from (irb):2:in `<module:Foobar>'
    from (irb):1

屏幕投射

4

5 回答 5

6

令牌表示一个命名空间,::如果之前没有直接使用任何东西,它会访问顶级命名空间。因此,例如,以这个小程序为例:

class Bar
  def initialize
    puts "New ingot created"
  end
end

module Foo
  class Bar
    def initialize(location)
      puts "New bar built in #{location}".
    end
  end

  def self.new_bar(which)
    if which == :top
      Bar.new("Rubytown, USA")
    else
      ::Bar.new
    end
  end
end

如果您致电,则会打印Foo.new_bar(:top)该消息。New bar built in Rubytown, USA如果改为使用,比如说,Foo.new_bar(:place_to_drink)它会打印New ingot created“.

于 2012-06-06T16:09:12.050 回答
2

此代码有效:

class Product
end

module Foo
  class Product < ::Product
  end
end

关键是命名空间:你在全局命名空间中定义第一个 Product(即 Object,so Object::Product == ::Product)(就像在 javascriptfoo = bar中等于window.foo = bar

相反,module Foo; class Product在模块 Foo 范围内,所以等于Foo::Product. 所以可以这样写前面的例子:

class Object::Product
end

module Object::Foo
  class Object::Foo::Product < Object::Product
  end
end

意思是一样的。

于 2012-06-06T16:10:48.377 回答
2

::Product 在顶级命名空间中查找 Product 类。在这种情况下,它正在访问现有模型。从铁轨演员:

我们要做的是在 ProductsController 中创建一个新的 Product 类,它继承自我们现有的 Product 模型类并在那里进行更改。

于 2012-06-06T16:12:44.097 回答
0

< 表示继承自

:: 表示命名空间,但如果以 :: 开头表示没有命名空间

class Product < ::Product 表示类 Product 继承自位于当前命名空间之外的另一个类 Product

于 2012-06-06T16:19:02.650 回答
0

About the error you have, don't use irb use rails console (IRB doesn't load rails app, see http://guides.rubyonrails.org/command_line.html#rails-console)

于 2012-06-06T16:23:18.943 回答