5

请参见下面的示例,我想最好使用第二种方法,但第一种方法也可以。哪种方法最好,使用另一种方法的后果是什么?

class Test 
  def start 
    p "started"
  end
  test = Test.new 
  test.start 
end 

class Test2
  def start 
    p "started"
  end
end
test2 = Test2.new 
test2.start 
4

4 回答 4

4

我肯定会说第二种变体更有意义。第一个不会导致错误,但对象实例化完全过时且毫无意义。外部变量在类的范围内不可见:

var = "string"

class A
  var = A.new
end

puts var #=> string

没有闭包,外部var与类内部不同。这意味着您的对象在创建后“丢失”并且将无法再访问,并最终受到 GC 的影响。

当您说第一个示例“有效”时,在此上下文中工作意味着可以在类范围内创建该对象后立即对该新创建的对象调用方法。但是不可能将该对象作为参考以供以后使用(不将其分配给类(实例)变量)。

如果您不需要参考以供以后使用,并且您确实想要执行这样的“一次性”操作,那么使用可以在不实例化对象的情况下调用的类方法或在initialize,如果这是必须在每次实例化时完成的事情。

于 2012-05-25T11:43:27.963 回答
3

您可以通过多种方式做到这一点,这取决于您。这是一个有趣的...

class Test 
  def start 
    p "started"
  end
  new 
end.start

更严重的是,您的第一个示例将所有内容封装在一个类中。没关系,对于脚本;它将所有内容都放在您自己的名称空间中,并且主要避免了神秘的主要对象上下文。如果需要,您可以定义嵌套类。

然而,第二种方法更传统。

于 2012-05-25T11:01:54.677 回答
3

定义一个在加载时创建自身对象的类不是一个好主意。该对象仅对其自身可用,而对其父范围不可用(当然您仍然可以通过 访问它ObjectSpace::each_object)。

于 2012-05-25T11:13:19.960 回答
2

Ruby 类的一些最佳实践

  • 在类定义中使用一致的结构。
  • 不要在类中嵌套多行类。尝试将这样的嵌套类分别放在它们自己的文件中,该文件夹的名称类似于包含类。
  • 更喜欢模块而不是只有类方法的类。仅当使用类创建实例有意义时才应使用类。
  • 当您想将模块的实例方法转换为类方法时,优先使用 module_function 而不是 extend self。
  • 在设计类层次结构时,请确保它们符合 Liskov 替换原则。
  • 尽量让你的课SOLID
  • 始终to_s为表示域对象的类提供适当的方法。
  • 使用 attr 系列函数来定义平凡的访问器或修改器。
  • 避免使用attr. 使用attr_readerandattr_accessor代替。
  • 考虑使用Struct.new,它为您定义了简单的访问器、构造器和比较运算符。
  • 不要扩展由Struct.new. 扩展它会引入一个多余的类级别,并且如果多次需要该文件也可能会引入奇怪的错误。
  • 考虑添加工厂方法以提供其他合理的方法来创建特定类的实例。
  • 喜欢鸭式打字而不是继承。
  • 避免使用类(@@)变量,因为它们在继承中的“讨厌”行为。
  • 根据预期用途为方法(私有、受保护)分配适当的可见性级别。不要将所有内容都公开(这是默认设置)。毕竟我们现在用 Ruby 编码,而不是用 Python。
  • 缩进publicprotectedprivate方法,就像它们适用的方法定义一样。在可见性修饰符上方留一个空行,在下面留一个空行,以强调它适用于它下面的所有方法。
  • 使用 def self.method 定义类方法。这使得代码更容易重构,因为类名不重复。

这是 ruby​​ 最佳实践的最佳文档:https ://github.com/bbatsov/ruby-style-guide

于 2015-12-10T13:17:37.930 回答