блок взломать, как упростить блок - PullRequest
1 голос
/ 12 февраля 2012

У меня есть вопрос по поводу блоков Ruby. Например, у меня есть класс Ruby:

class NewClass
  def initialize
    @a = 1
  end

  def some_method
    puts @a
  end
end

Когда я делаю что-то подобное:

NewClass.new do |c|
  c.some_method
end

Все хорошо, но есть ли возможность сделать это как-то так:

NewClass.new do
  some_method
end

Есть идеи?

Ответы [ 3 ]

2 голосов
/ 12 февраля 2012
class NewClass
  def initialize(&block)
    @a = 1
    instance_eval(&block)
  end

  def some_method
    puts @a
  end
end



NewClass.new do
  some_method
end
2 голосов
/ 12 февраля 2012

Ваш текущий код будет просто игнорировать блок, так как вы не yield к нему.Для того, что вы пытаетесь сделать в первом примере, вам нужна идиома yield self в initialize.

Для того, зачем вам сначала нужна переменная блока, подумайте о том, каким будет получатель для some_method во втором примере.Без явного получателя это верхний уровень main (если, конечно, этот код не является частью какого-то другого класса, где этот включающий класс будет self).См. Пост в блоге Дэйва Томаса Изменение себя в Ruby (или пост Иегуды Каца , как указал Никлас Б. в комментариях) для получения дополнительной информации по этой теме (комментарии проясняютсячасть "proc prococation").

Редактировать: все, что сказано, похоже, работает, но я предпочитаю версию yield self и пример 1:

class NewClass
  def initialize
    @a = 1
  end

  def some_method
    puts "Hello: #@a"
  end

  def self.build(&block)
    x = self.new
    x.instance_eval(&block)
    x
  end
end

NewClass.build do
  some_method
end

Это позволяет вамвыполнить блок без переменной блока и вернет новый экземпляр класса для присвоения переменной и т. д.

0 голосов
/ 12 февраля 2012

Использование instance_eval должно сделать эту работу. Но если вы не знаете, что делаете (и это не просто из-за лени), я бы посоветовал вам противостоять этому и продолжу ваш оригинальный подход.

def initialize(&block)
  @a = 1
  self.instance_eval(&block) if block_given?
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...