开发者

Creating object instance

开发者 https://www.devze.com 2023-02-06 18:09 出处:网络
Is there a difference between x = Class.new( or method) x.method and开发者_高级运维 Class.new(or method) do |x|

Is there a difference between

x = Class.new( or method)
x.method

and开发者_高级运维

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


x = SomeClass.new
x.some_method

This first creates an instance of SomeClass (calling initialize with no arguments). It then calls the method some_method on that instance.

SomeClass.new do |x|
  x.some_method
end

This creates an instance of SomeClass, calling initialize with a block as its argument. That block takes one argument and calls some_method on that argument. Whether and how often the block will be called and what the argument will be depends entirely on what SomeClass's initialize method does.

In many cases the pattern

SomeClass.some_creation_method do |x|
  x.some_method
end

is used, so that some_creation_method creates a SomeClass instance, yields it to the block and then frees all the resources used by that instance after the block finishes (e.g. it could close file handles, delete temporary files etc.). This is what File.open does.


In the case where the class in question is literally Class the block will be class_evaled on the newly created class, i.e.

c = Class.new do
  some_code
end

is equivalent to

c = Class.new
c.class_eval do
  some_code
end


Depends on the class. e.g. for File objects,

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

the file handle will be closed automatically when the block exits. But that's only the idiom, in general the class defines the semantics, and chooses if it supplies the variant with the block.


Here is a simple example showing that the two are not equivalent. They would only be equivalent if the initialize method of your class called yield(self) at the end.

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)

In the second example, I pass a block to new, but since my initialize method doesn't do anything with the block, the contents of the block are never run.

0

精彩评论

暂无评论...
验证码 换一张
取 消