Доступ к методам модуля с :: - PullRequest
7 голосов
/ 16 февраля 2012

Документация, которую я прочитал, подсказывает мне использовать Module.method для доступа к методам в модуле. Однако я также могу использовать Module :: method. Это синтаксический сахар, или я запутался?

module Cat
    FURRY_LEVEL = 4

    def self.sound
        %w{meow purr hiss zzzz}.sample
    end
end

puts Cat.sound          # This works.
puts Cat::sound         # This also works.  Why?!

puts Cat.FURRY_LEVEL    # Expected error occurs here.
puts Cat::FURRY_LEVEL   # This works.

Ответы [ 2 ]

9 голосов
/ 16 февраля 2012

Постоянное разрешение всегда требует использования ::.

Вызов метода является идиоматически и обычно является периодом (.), но :: также допустим. Это верно не только для так называемых модульных методов, но и для вызова любого метода для любого объекта:

class Foo
  def bar
    puts "hi"
  end
end

Foo.new::bar
#=> hi

Это не столько «синтаксический сахар», сколько просто альтернативный синтаксис, такой как возможность писать if или case операторов либо с новой строки, then и новой строки, либо просто then.

Это специально разрешено, потому что Ruby допускает методы с тем же именем, что и константа, и иногда имеет смысл думать, что это один и тот же элемент:

class Foo
  class Bar
    attr_accessor :x
    def initialize( x )
      self.x = x
    end
  end
  def self.Bar( size )
    Foo::Bar.new( size ) 
  end
end

p Foo::Bar     #=> Foo::Bar                    (the class)
p Foo::Bar(42) #=> #<Foo::Bar:0x2d54fc0 @x=42> (instance result from method call)

Это часто встречается в Ruby в библиотеке Nokogiri , которая имеет (например) модуль Nokogiri::XML, а также Nokogiri.XML метод. При создании документа XML многие люди предпочитают писать

@doc = Nokogiri::XML( my_xml )

Вы видите это также в библиотеке Sequel , где вы можете написать:

class User < Sequel::Model                      # Simple class inheritance
class User < Sequel::Model(DB[:regular_users])  # Set which table to use

Опять же, у нас есть метод (Sequel.Model) , названный так же, как константа (Sequel :: Model) . Вторая строка также может быть записана как

class User < Sequel.Model(DB[:regular_users])

& hellip; но выглядит не так хорошо.

5 голосов
/ 16 февраля 2012

:: называется scope resolution operator, который используется для определения того, под каким scope определен method, class or constant.

В следующем примере мы используем :: для доступа к классу Base, который определен в модуле ActiveRecord

ActiveRecord::Base.connection_config
# => {:pool=>5, :timeout=>5000, :database=>"db/development.sqlite3", :adapter=>"sqlite3"}

Мы используем :: для доступа к постоянным, определенным в модуле

> Cat::FURRY_LEVEL
=> 4
> Cat.FURRY_LEVEL
=> undefined method `FURRY_LEVEL' for Cat:Module (NoMethodError)

Оператор . используется для вызова module method (определяется с помощью self.) Модуля.

Сводка: Несмотря на то, что оба :: и .делает ту же работу здесь, он используется для разных целей.Вы можете прочитать больше от здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...