From: Logan Capaldo Date: 2006-05-09T04:22:20+09:00 Subject: Re: How can I write the awesome kind of code? On May 8, 2006, at 3:13 PM, Pat Maddox wrote: > On 5/8/06, Logan Capaldo wrote: >> >> On May 8, 2006, at 2:38 PM, Pat Maddox wrote: >> >> > I'm writing a small app to do poker simulations. I read a lot of >> > blogs in which the author shows off his cool DSL. I decided I >> want to >> > be able to specify a poker hand in my app like >> > >> > hand "my_hand" do >> > players 10 >> > chips 1000 >> > end >> > >> > my_hand.foo >> > >> > How can I do something like that? >> > >> > Pat >> > >> >> class Hand >> def initialize(name, &block) >> @name = name >> if block >> instance_eval(&block) >> end >> self >> end >> def players(i) >> @players = i >> end >> >> def chips(i) >> @chips = i >> end >> >> def foo >> puts self.inspect >> end >> end >> >> def hand(name, &block) >> Hand.new(name, &block) >> end >> >> >> my_hand = hand "my_hand" do >> players 10 >> chips 1000 >> end >> >> my_hand.foo >> >> # >> >> If you want to automatically set 'my_hand' you can put it inside an >> enclosing object and dynamically define the my_hand method >> >> >> >> >> >> > > Hey Logan, > > Thanks for the input. Here's what I ended up with. I don't know if > I'm doing bad stuff though to define the object - please let me > know. In the hand method, I'm creating the hand and passing the > block like > normally. Then to let me call the hand by the name I pass in, I > define a new method that calls a closure that simply returns the value > of the newly created object. It works great...I just don't know if > there's a better way, or if this is a bad approach. > > class Hand > def players(p = nil) > @players = p unless p.nil? > @players > end > > def chips(c = nil) > @chips = c unless c.nil? > @chips > end > end > > def hand(name, &init) > h = Hand.new > yield(h) if block_given? > self.class.class_eval { define_method(name) { proc { h }.call } } > h > end > > hand "my_hand" do |h| > h.players 10 > h.chips 1000 > end > > puts my_hand.inspect > proc { h }.call is redundant. define_method(name) { h } should work Though I question whether hand name { ... } is necessary. Why not just do my_hand = hand do |h| h.players 10 h.chips 1000 end puts my_hand.inspect