创建对象实例

时间:2011-01-26 20:01:28

标签: ruby

之间有区别吗?
x = Class.new( or method)
x.method

Class.new(or method) do |x|
x.method
end

3 个答案:

答案 0 :(得分:6)

x = SomeClass.new
x.some_method

首先创建SomeClass的实例(不带参数调用initialize)。然后它调用该实例上的方法some_method

SomeClass.new do |x|
  x.some_method
end

这会创建一个SomeClass的实例,以块作为参数调用initialize。该块接受一个参数并在该参数上调用some_method。块的调用次序和频率是多少以及论证的内容完全取决于SomeClass的初始化方法的作用。

在许多情况下,模式

SomeClass.some_creation_method do |x|
  x.some_method
end
使用

,以便some_creation_method创建一个SomeClass实例,将其生成块,然后在块完成后释放该实例使用的所有资源(例如,它可以关闭文件句柄,删除临时文件等)。这就是File.open的作用。


如果所讨论的类字面上是Class,则该块将在新创建的类上class_eval,即

c = Class.new do
  some_code
end

相当于

c = Class.new
c.class_eval do
  some_code
end

答案 1 :(得分:1)

取决于课程。例如对于File个对象,

File.open("foo.txt", "wb") do |f|
  f.write("x")
end

当块退出时,文件句柄将自动关闭。但这只是成语,一般来说,类定义语义,并选择是否为变量提供块。

答案 2 :(得分:1)

这是一个简单的例子,显示两者不相等。只有当您的班级的initialize方法在结尾处调用yield(self)时,它们才是等效的。

class MyClass
  def initialize( name )
    @name = name
  end
  def say_hi
    puts "Hi, I am #{@name}"
  end
end

x = MyClass.new( "Bob" )
x.say_hi
#=> Hi, I am Bob

MyClass.new( "Jim" ) do |x|
  x.say_hi
end
#=> (nothing prints out)

在第二个示例中,我将一个块传递给new,但由于我的initialize方法对块没有任何作用,因此块的内容永远不会运行。