首页 > 解决方案 > 点(.)和双冒号(::)在访问类​​方法中的区别

问题描述

双冒号 (::) 允许在类或模块中定义的常量、实例方法和类方法从类或模块之外的任何地方访问。

看这个例子:

class Sample
   VAR_SAMPLE="what is the difference?"

  def self.show_var
    return VAR_SAMPLE
  end

  def method2
    return VAR_SAMPLE
  end
end

puts Sample::show_var # => what is the difference?
puts Sample.show_var # => what is the difference?
puts Sample::new::method2 # => what is the difference?
puts Sample.new.method2 # => what is the difference?

那么使用点(。)和双冒号(::)运算符访问类方法有什么区别?任何想法表示赞赏。

标签: ruby

解决方案


双冒号::命名空间运算符也可以用作消息发送运算符。换句话说,

foo.bar

也可以写成

foo::bar

除非没有。

特别.始终是消息发送。::通常命名空间查找,除非不可能。这意味着,例如,您不能调用以大写字符开头的消息,除非您还传递了参数列表。

foo = Class.new do
  def BAR; :method end
  BAR = :constant
end

foo.BAR    #=> :method
foo::BAR   #=> :constant
foo::BAR() #=> :method

::也可以用于消息发送的事实是历史上的好奇心,并且在大多数样式指南中被禁止,除了“类工厂”,即返回类的方法。想象一下这样设置的 Web 框架:

module Controller
  def self.R(path)
    Class.new(AbstractController) do
      # a bunch of methods for dealing with routing to `path`
    end
  end
end

class IndexController < Controller::R '/index.html'
  def get
    render 'Welcome'
  end
end

在这种情况下,在某些风格指南中,这样写是可以接受的,Controller::R因为尽管R它是一个方法,但它返回一个类,所以它有点像一个。

但这是某些 DSL 的特殊情况,仅在某些样式指南中允许。大多数样式指南不允许::发送消息,因为它与 冗余.,因为它已经具有另一个不同的含义(命名空间解析),并且因为它的行为并非.在所有情况下都如此。

那么使用点(。)和双冒号(::)运算符访问类方法有什么区别?

一方面,您可以说没有区别,因为当用作消息发送运算符时,它们都做完全相同的事情。

另一方面,语法有所不同,即不是消息发送,而是完全不同的名称空间查找。from ,这是一条消息发送。foo::BAR foo.BAR


推荐阅读