Accessing module methods with ::

后端 未结 2 936
無奈伤痛
無奈伤痛 2021-01-12 09:14

Documentation I\'ve read tells me to use Module.method to access methods in a module. However, I can use Module::method as well. Is this syntactic sugar, or am I confused?

2条回答
  •  滥情空心
    2021-01-12 09:55

    Constant resolution always requires that you use ::.

    Method invocation is idiomatically and usually a period (.), but :: is also legal. This is not just true for so-called module methods, but for invoking any method on any object:

    class Foo
      def bar
        puts "hi"
      end
    end
    
    Foo.new::bar
    #=> hi
    

    It's not so much "syntax sugar" as it is simply alternative syntax, such as the ability to write if or case statements with either a newline, then and newline, or just then.

    It is specifically allowed because Ruby allows methods with the same name as a constant, and sometimes it makes sense to think that they are the same item:

    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) #=> # (instance result from method call)
    

    You see this commonly in Ruby in the Nokogiri library, which has (for example) the Nokogiri::XML module as well as the Nokogiri.XML method. When creating an XML document, many people choose to write

    @doc = Nokogiri::XML( my_xml )
    

    You see this also in the Sequel library, where you can write either:

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

    Again, we have a method (Sequel.Model) named the same as a constant (Sequel::Model). The second line could also be written as

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

    …but it doesn't look quite as nice.

提交回复
热议问题