加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby – 如何在特征类中使模块常量也可见?

发布时间:2020-12-17 03:10:38 所属栏目:百科 来源:网络整理
导读:我创建了一个包含常量NAME和方法hello的模块.如果类包含模块,则两个定义应在不同范围内可见. module A NAME = 'Otto' def self.included(base) base.extend(ClassMethods) end def hello(name = 'world') self.class.hello(name) end module ClassMethods de
我创建了一个包含常量NAME和方法hello的模块.如果类包含模块,则两个定义应在不同范围内可见.

module A
  NAME = 'Otto'
  def self.included(base)
    base.extend(ClassMethods)
  end

  def hello(name = 'world')
    self.class.hello(name)
  end

  module ClassMethods
    def hello(name = 'world')
      "Hello #{name}!"
    end
  end
end

class B
  include A

  def instance_scope
    p [__method__,hello(NAME)]
  end

  def self.class_scope
    p [__method__,hello(NAME)]
  end

  class << self
    def eigen_scope
      p [__method__,hello(NAME)]
    end
  end
end

B.new.instance_scope
B.class_scope
B.eigen_scope

#=> script.rb:34:in `eigen_scope': uninitialized constant Class::NAME (NameError)
    from script.rb:41

但是该常量在本征类的实例方法范围中是不可见的,类<<自. 有没有办法使模块更健壮,并在上面的错误范围内提供常量?

解决方法

class << self
  def eigen_scope
    p [__method__,hello(self::NAME)]
    #=> [:eigen_scope,"Hello Otto!"]
  end
end

为什么self :: NAME有效?

> A :: NAME将是最简单的硬编码版本.
> B :: NAME也可以,因为B包括A.
>在eigen_scope里面,self是B,所以self :: NAME也可以
> self :: NAME也可以在self.class_scope中使用
> self :: NAME在instance_scope中不起作用:B实例不是类/模块.

为什么NA??ME不起作用?

Here是一个非常好的解释.

constant lookup searches for constants that are defined in
Module.nesting,Module.nesting.first.ancestors,and
Object.ancestors if Module.nesting.first is nil or a module

self在class_scope和eigen_scope中是相同的.

尽管如此,Module.nesting是不同的:

> [B]用于class_scope
> [#< Class:B>,B]用于eigen_scope

所以Module.nesting.first.ancestors是:

> class_scope的[B,A,Object,Kernel,BasicObject]
eigen_scope的[#< Class:B>,A :: ClassMethods,#< Class:Object>,#< Class:BasicObject>,Class,Module,BasicObject]

A没有被搜索,但是A :: ClassMethods!

所以你可以定义:

module A
  module ClassMethods
    NAME = 'Bob'
  end
end

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读