ruby - Foo 类有什么区别? end & Foo = Class.new(和模块​​/模块)?

标签 ruby semantics

我花了一段时间调试一个问题,我在使用 Module 而不是 module 来声明模块时打错了字。为什么 Ruby 有 moduleModule(以及类似的 classClass),具有不同的语义?请参见下面的示例:

class C; end; # ok
Class C2; end; # error
C3 = class.new # error
C4 = Class.new # ok

拥有两种仅大小写不同的不同构造似乎令人困惑。

最佳答案

类 Foo; endFoo = Class.new 大致相同,但存在一些关键差异。所有这些也适用于 module Bar; endBar = Module.new

  • class is a keywordClass is simply a constant name和其他人一样。

  • Class.new 允许创建匿名(未命名)类,而 class; end 是语法错误。这使得前者对元编程更有用。

  • class 创建新的词法作用域,而 Class.new do ... end 则不会。例如:

    class Foo; BAR = 42; end
    Baz = Class.new { QUX = 42 }
    BAR       #   NameError: uninitialized constant BAR
    Foo::BAR  #=> 42
    QUX       #=> 42
    Baz::QUX  #=> 42  (warning: toplevel constant QUX referenced by Baz::QUX)
    
  • 由于 Class.new do ... end 是一个闭包,您可以关闭局部变量。 class ... end 不能。例如

    foo = 42
    class Foo; puts foo; end  # NameError: undefined local variable or method `foo' for Foo:Class
    Class.new { puts foo }    # (prints 42)
    
  • class 立即命名类,而 Class.new does it on assignment (last) .

  • Class.new 不能用于重新打开现有类(必须使用 class_exec 或类似的),而 class Foo; end 重新打开 Foo(如果它已经存在并且是一个类)。

除了功能差异之外,关键字语法可以说更易于阅读,类似于 {}Hash.new[] 与. Array.new.

关于ruby - Foo 类有什么区别? end & Foo = Class.new(和模块​​/模块)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23772666/

相关文章:

ruby - 使用 Ruby Net::HTTP 的 curl 任务

java - 无法扩展 Node_Literal Jena 类

java - Java 是否有不明确的语法,需要有关标识符的更多信息?

c++ - C++ 中的默认传递引用语义

css - Rails 4 : SASS background image works locally, 在 AWS 中失败

Ruby shell 命令评估不适用于别名

ruby-on-rails - 如何将参数传递给符号方法调用

ruby-on-rails - 这是错误处理反模式吗?

terminology - 为什么程序员会将术语 "assembler"与 "assembly"混淆?

c++ - char a[] 的语义