Создание экземпляра объекта - PullRequest
0 голосов
/ 26 января 2011

Есть ли разница между

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

и

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

Ответы [ 3 ]

6 голосов
/ 26 января 2011
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 голос
/ 26 января 2011

Вот простой пример, показывающий, что оба не эквивалентны.Они будут эквивалентны только в том случае, если метод 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 метод ничего не делает с блоком, содержимое блока никогда не запускается.

1 голос
/ 26 января 2011

Зависит от класса. например для File объектов,

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

дескриптор файла будет автоматически закрыт при выходе из блока. Но это только идиома, в общем случае класс определяет семантику и выбирает, предоставляет ли он вариант с блоком.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...