2012-06-06 3 views
0

The 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 

screen casts

ответ

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»

+0

Я думаю, что ваше объяснение (последнее предложение) должно быть обратным. Если вы назовете 'Foo.new_bar (: top)', он должен напечатать '' Новый бар, построенный в Rubytown, USA''. – Devaroop

+0

А, хороший улов. Починил это. – Jwosty

2

Этот код работает:

class Product 
end 

module Foo 
    class Product < ::Product 
    end 
end 

Ключ имен: вы определяете первый продукт в глобальном пространстве имен (то есть объект, так Object::Product == ::Product) (например, в JavaScript foo = 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 

Значение такое же.

+1

этот я считаю более понятным. –

2

:: Продукт ищет в пространстве имен верхнего уровня для класса Product. В этом случае он обращается к существующей модели. Из направляющих рельсов:

Что мы будем делать, это создать новый класс Product внутри ProductController, который наследуется от нашего существующего класса модели продукта и вносить туда изменения.

0

< средства наследовать от

:: означает пространство имен, но если начинается с :: означает без имен

< класс продукта :: означает продукт класса продукта наследоваться от другого класса продукта, находящегося за пределами текущего пространства имен

Смежные вопросы