# How can I write the awesome kind of code?

**URL:** <https://www.ruby-forum.com/t/how-can-i-write-the-awesome-kind-of-code/59932>\
**Category:** Ruby\
**Created:** [May 8, 2006, 8:40pm UTC](https://www.ruby-forum.com/t/how-can-i-write-the-awesome-kind-of-code/59932 "2006-05-08T20:40:14Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [May 8, 2006, 8:40pm UTC](https://www.ruby-forum.com/t/how-can-i-write-the-awesome-kind-of-code/59932/1 "2006-05-08T20:40:14Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [May 8, 2006, 8:49pm UTC](https://www.ruby-forum.com/t/how-can-i-write-the-awesome-kind-of-code/59932/2 "2006-05-08T20:49:43Z")

</div>

On May 8, 2006, at 1:38 PM, Pat M. wrote:

> How can I do something like that?

class Hand  
…  
end

def hand( …, &init )  
Hand.new( … ).instance\_eval(&init)  
end

I really think you’ll be happy in the long run though if you drop the  
instance\_eval() and pass the hand into the block instead.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [May 8, 2006, 8:59pm UTC](https://www.ruby-forum.com/t/how-can-i-write-the-awesome-kind-of-code/59932/3 "2006-05-08T20:59:03Z")

</div>

On May 8, 2006, at 2:38 PM, Pat M. wrote:

> 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

#\<Hand:0x363450 @name=“my\_hand”, @chips=1000, @players=10\>

If you want to automatically set ‘my\_hand’ you can put it inside an  
enclosing object and dynamically define the my\_hand method

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [May 8, 2006, 9:02pm UTC](https://www.ruby-forum.com/t/how-can-i-write-the-awesome-kind-of-code/59932/4 "2006-05-08T21:02:03Z")

</div>

On 5/8/06, James Edward G. II [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > 
> 
> end
> 
> I really think you’ll be happy in the long run though if you drop the  
> instance\_eval() and pass the hand into the block instead.
> 
> James Edward G. II

Okay so now I have

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(&init)  
yield(Hand.new) if block\_given?  
end

hand do |h|  
h.players 10  
h.chips 1000  
end

Does that look right?

How can I use the Hand object that I just created?

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [May 8, 2006, 9:14pm UTC](https://www.ruby-forum.com/t/how-can-i-write-the-awesome-kind-of-code/59932/5 "2006-05-08T21:14:29Z")

</div>

On May 8, 2006, at 1:59 PM, Pat M. wrote:

> > > chips 1000  
> > > def hand( …, &init )  
> > > Okay so now I have  
> > > end
> 
> Does that look right?

You can remove the &init parameter to hand(), since you are using  
yield. You may also want to make players() and chips() more Rubyish  
with players=() and chips=().

To keep the hand object you could have hand return it, or perhaps add  
it to some global Hash by name.

Hope that helps.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [May 8, 2006, 9:24pm UTC](https://www.ruby-forum.com/t/how-can-i-write-the-awesome-kind-of-code/59932/6 "2006-05-08T21:24:04Z")

</div>

On May 8, 2006, at 3:13 PM, Pat M. wrote:

> > > players 10  
> > > class Hand
> > 
> > ```
> > Hand.new(name, &block)
> > 
> > ```
> > 
> > #\<Hand:0x363450 @name=“my\_hand”, @chips=1000, @players=10\>  
> > Hey Logan,  
> > class Hand
> 
> 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

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [May 8, 2006, 9:27pm UTC](https://www.ruby-forum.com/t/how-can-i-write-the-awesome-kind-of-code/59932/7 "2006-05-08T21:27:12Z")

</div>

On 5/8/06, James Edward G. II [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > > > hand “my\_hand” do  
> > > > end
> > 
> > @chips = c unless c.nil?  
> > h.chips 1000
> 
> Hope that helps.
> 
> James Edward G. II

I took out &init, I understand why I don’t need that in there.

However after doing all this, I’m not sure I get any benefit,  
particularly if I stick to the more Rubyish players= and chips=

hand “my\_hand” do |h|  
h.chips = 1000  
h.players = 10  
end

vs

my\_hand = Hand.new  
my\_hand.chips = 1000  
my\_hand.players = 10

It’s basically the same…

Pat

---

<div class="post-metadata">

**Author:** ![pergesu](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/22d042/32.png) [@pergesu](https://www.ruby-forum.com/u/pergesu)\
**Post date:** [May 8, 2006, 9:14pm UTC](https://www.ruby-forum.com/t/how-can-i-write-the-awesome-kind-of-code/59932/8 "2006-05-08T21:14:40Z")

</div>

On 5/8/06, Logan C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > end  
> > @name = name  
> > @chips = i
> 
> 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
