Он называется домен-специфическим языком (DSL). Вот (последняя заархивированная версия) отличная информация о различных формах блоков Ruby DSL.
Существует два способа сделать это с разными синтаксисами:
do_thing do |thing| # with a block parameter
thing.foo :bar
thing.baz :wibble
end
# versus
do_thing do # with block-specific methods
foo :bar
baz :wibble
end
Первый более явный и менее вероятный сбой, а второй более краткий.
Первый может быть реализован так, просто передавая новый экземпляр как блокпараметр с yield
:
class MyThing
def self.create
yield new
end
def foo(stuff)
puts "doing foo with #{stuff}"
end
end
MyThing.create do |thing|
thing.foo :bar
end
И второй, который запускает блок в контексте нового объекта, предоставляя ему доступ к self
, переменным экземпляра и методам:
class MyThing
def self.create(&block)
new.instance_eval &block
end
def foo(stuff)
puts "doing foo with #{stuff}"
end
end
MyThing.create do
foo :bar
end
И если вы действительно хотите сделать это без звонка MyThing.create
, просто:
def create_thing(&block)
MyThing.create &block
end