I have this class:
class Items
def initialize &block
(block.arity < 1 ? (instance_eval &block) : block.call(self)) if block_given?
end
def button_id button_id=nil
unless @button_id.present?
raise "button_id must be supplied" if button_id.nil?
@button_id = button_id
end
@button_id
end
end
Now, when I do this it works:
Items.new do
button_id 1
end
But when I do this, it fails because I think it is not on the same scope:
@button = Button.find(params[:button_id]
Items.new do
button_id @button.id
end
How can fix this to take arguments outside the scope?
Thanks!
Try this:
class Items
def self.dsl
new.tap do |item|
yield item
end
end
def button_id(button_id)
@button_id = button_id
end
end
@button = Button.find(params[:button_id])
item = Items.dsl do |item|
item.button_id(@button.id)
end
puts item.inspect
Turns out all I needed to do was to pass the arguments to the block like this:
Items.new do |item|
item.button_id @button.id
end
Less beautiful DSL but works.
I don't think this is the right use case of DSL, when you can simply assign the attributes by arguments.
class Item
attr_accessor: :button_id
def initialize(args)
button_id = args[:button_id]
end
end
Another problem is in your usage. The instance would be of little value if you don't assign it to a variable
item = Item.new button_id: button_id
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.