ruby – “A级之间的差异; B级“和”A类:: B“

前端之家收集整理的这篇文章主要介绍了ruby – “A级之间的差异; B级“和”A类:: B“前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有什么区别:
class A
  class B
  end
end

和@H_301_5@

class A
end

class A::B
end

更新:这两种方法并不完全相同.@H_301_5@

在第二种方法中,B无法访问A中定义的常量.@H_301_5@

此外,正如Matheus Moreira所说,在第二种方法中,必须在定义A :: B之前定义A.@H_301_5@

还有什么其他差异?@H_301_5@

解决方法

在Ruby中,模块和类分别是 ModuleClass类的实例.它们从它们被赋予的常量中得出它们的名称.当你写:
class A::B
  # ...
end

你是在写作:@H_301_5@

A::B ||= Class.new do
  # ...
end

哪个是有效的常量赋值语法,并假设A常量已正确初始化,并且它指的是模块或类.@H_301_5@

例如,考虑如何定义类:@H_301_5@

class A
  # ...
end

实际发生的是:@H_301_5@

Object::A ||= Class.new do
  # ...
end

现在,当你写:@H_301_5@

class A
  class B
    # ...
  end
end

实际发生的事情如下:@H_301_5@

(Object::A ||= Class.new).class_eval do
  (A::B ||= Class.new).class_eval do
    # ...
  end
end

这是正在发生的事情,按顺序:@H_301_5@

>除非已初始化,否则新的Class实例将被赋予Object的A常量.
>新的Class实例被赋予A的B常量,除非它已经初始化.@H_301_5@

这样可以在尝试定义任何内部类之前确保所有外部类的存在.@H_301_5@

范围也有变化,允许您直接访问A的常量.相比:@H_301_5@

class A
  MESSAGE = "I'm here!"
end

# Scope of Object
class A::B
  # Scope of B
  puts MESSAGE  # NameError: uninitialized constant A::B::MESSAGE
end

# Scope of Object
class A
  # Scope of A
  class B
    # Scope of B
    puts MESSAGE  # I'm here!
  end
end

根据this blog post,Ruby核心团队将“当前类”称为cref.不幸的是,作者没有详细说明,但正如他所指出的那样,它与自我的背景是分开的.@H_301_5@

As explained here,cref是一个链表,表示模块在某个时间点的嵌套.@H_301_5@

The current cref is used for constant and class variable lookup and
for def,undef and alias.@H_301_5@

正如其他人所说,他们是表达同一事物的不同方式.@H_301_5@

然而,有一个微妙的区别.当你编写A :: B类时,你假设已经定义了A类.如果没有,您将获得NameError,并且根本不会定义B.@H_301_5@

编写正确嵌套的模块:@H_301_5@

class A
  class B
  end
end

在尝试定义B之前确保A类存在.@H_301_5@

猜你在找的Ruby相关文章