# Something.new( :attribute =\> value) thing

**URL:** <https://www.ruby-forum.com/t/something-new-attribute-value-thing/174994>\
**Category:** Ruby\
**Created:** [September 5, 2009, 1:29pm UTC](https://www.ruby-forum.com/t/something-new-attribute-value-thing/174994 "2009-09-05T13:29:53Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![kingkadelfek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/8edcca/32.png) [@kingkadelfek](https://www.ruby-forum.com/u/kingkadelfek)\
**Post date:** [September 5, 2009, 1:29pm UTC](https://www.ruby-forum.com/t/something-new-attribute-value-thing/174994/1 "2009-09-05T13:29:53Z")

</div>

Hello, I saw something very interesting in the code of FXRuby, and I  
would like to use this kind of code in my scripts :

My\_Window.new(app, “Button Test”, :opts =\> DECOR\_ALL, :x =\> 100, :y =\>  
100)

I’m only able to do “classic” initialisations, such as :  
My\_Window.new(app, “Button Test”, DECOR\_ALL, 100, 100)

What is the easiest way to create class which use the ":opts =\> … x =\>  
… y =\> " part ?  
I’m sorry, I don’t know the name of this feature, so it’s quite  
difficult to find informations about it.

I wrote a code to use for sample.

class My\_Window

attr\_accessor :application  
attr\_accessor :title

# Do I have to create attributes ?

attr\_accessor :opts  
attr\_accessor :x  
attr\_accessor :y

def initialize(application, title, ??? )

```
@application = application
@title = title

???

```

end

end

Thanks !

---

<div class="post-metadata">

**Author:** ![kingkadelfek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/8edcca/32.png) [@kingkadelfek](https://www.ruby-forum.com/u/kingkadelfek)\
**Post date:** [September 5, 2009, 1:59pm UTC](https://www.ruby-forum.com/t/something-new-attribute-value-thing/174994/2 "2009-09-05T13:59:23Z")

</div>

Marc-antoine Kruzik wrote:

> What is the easiest way to create class which use the ":opts =\> … x =\>  
> … y =\> " part ?  
> I’m sorry, I don’t know the name of this feature, so it’s quite  
> difficult to find informations about it.

When the trailing method arguments are key =\> value pairs, Ruby collects  
them into a hash and passes the hash as the last argument to the method.  
Frequently the keys are symbols such as :opts or :x. The keys don’t have  
to be symbols, though.

See [http://www.softiesonrails.com/2007/8/27/ruby-101-hashes-are-cool](http://www.softiesonrails.com/2007/8/27/ruby-101-hashes-are-cool)

---

<div class="post-metadata">

**Author:** ![kingkadelfek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/8edcca/32.png) [@kingkadelfek](https://www.ruby-forum.com/u/kingkadelfek)\
**Post date:** [September 5, 2009, 6:35pm UTC](https://www.ruby-forum.com/t/something-new-attribute-value-thing/174994/3 "2009-09-05T18:35:11Z")

</div>

On Sat, Sep 5, 2009 at 1:29 PM, Marc-antoine  
Kruzik[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hello, I saw something very interesting in the code of FXRuby, and I  
> would like to use this kind of code in my scripts :
> 
> My\_Window.new(app, “Button Test”, :opts =\> DECOR\_ALL, :x =\> 100, :y =\>  
> 100)

> What is the easiest way to create class which use the ":opts =\> … x =\>  
> … y =\> " part ?  
> I’m sorry, I don’t know the name of this feature, so it’s quite  
> difficult to find informations about it.

As Tim said, Ruby collects key-value pairs at the end of the argument  
list as a Hash. Here’s an example:

irb(main):007:0\> def test(a,b,c)  
irb(main):008:1\> p [a,b,c]  
irb(main):009:1\> p c.class  
irb(main):010:1\> c.each {|key,value| p [key,value]}  
irb(main):011:1\> end  
=\> nil  
irb(main):012:0\> test(1,2,:xxx =\> 5, :y =\> 55)  
[1, 2, {:xxx=\>5, :y=\>55}]  
Hash  
[:xxx, 5]  
[:y, 55]

Jesus.

---

<div class="post-metadata">

**Author:** ![kingkadelfek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/8edcca/32.png) [@kingkadelfek](https://www.ruby-forum.com/u/kingkadelfek)\
**Post date:** [September 5, 2009, 7:09pm UTC](https://www.ruby-forum.com/t/something-new-attribute-value-thing/174994/4 "2009-09-05T19:09:24Z")

</div>

Marc-antoine Kruzik wrote:

> # Do I have to create attributes ?
> 
> attr\_accessor :opts  
> attr\_accessor :x  
> attr\_accessor :y
> 
> def initialize(application, title, ??? )
> 
> ```
> @application = application
> @title = title
> 
> ???
> 
> ```
> 
> end
> 
> end

class A

def initialize(arg1, arg2, hash)  
hash.each do |key, val|  
A.send(:attr\_accessor, key)  
send("#{key}=", val)  
end  
end

end

a = A.new(“hello”, “world”, :x =\> 10, :y =\> 20, :z =\> “red”)  
puts a.x  
puts a.y  
puts a.z

–output:–  
10  
20  
red

a.x = “hello”  
a.y = “goodbye”  
a.z = “the end”

puts a.x  
puts a.y  
puts a.z

–output:–  
hello  
goodbye  
the end

---

<div class="post-metadata">

**Author:** ![kingkadelfek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/8edcca/32.png) [@kingkadelfek](https://www.ruby-forum.com/u/kingkadelfek)\
**Post date:** [September 5, 2009, 8:06pm UTC](https://www.ruby-forum.com/t/something-new-attribute-value-thing/174994/5 "2009-09-05T20:06:28Z")

</div>

Tim H. wrote:

> When the trailing method arguments are key =\> value pairs, Ruby collects  
> them into a hash and passes the hash as the last argument to the method.  
> Frequently the keys are symbols such as :opts or :x. The keys don’t have  
> to be symbols, though.
> 
> See [http://www.softiesonrails.com/2007/8/27/ruby-101-hashes-are-cool](http://www.softiesonrails.com/2007/8/27/ruby-101-hashes-are-cool)

I know the hashes, but I didn’t know what was the best way to use  
arguments this way (my first post). Nice link.

> A.send(:attr\_accessor, key)  
> send(“#{key}=”, val)

This solution is what I was looking for.  
With a bit of work, I will be able to write code like this :

a = A.new(“hello”, “world”, :x =\> 10, :y =\> 20, :z =\> “red”)  
a = A.new(“hello”, “world”, :z =\> “red”, :y =\> 20, :x =\> 10)  
a = A.new(“hello”, “world”, :z =\> “red”)  
a = A.new(“hello”, “world”, :x =\> 10)

Thank you very much, 7stud.

---

<div class="post-metadata">

**Author:** ![kingkadelfek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/8edcca/32.png) [@kingkadelfek](https://www.ruby-forum.com/u/kingkadelfek)\
**Post date:** [September 6, 2009, 4:36pm UTC](https://www.ruby-forum.com/t/something-new-attribute-value-thing/174994/6 "2009-09-06T16:36:59Z")

</div>

On Sun, 2009-09-06 at 03:06 +0900, Marc-antoine Kruzik wrote:

> > A.send(:attr\_accessor, key)  
> > send("#{key}=", val)
> 
> This solution is what I was looking for.  
> With a bit of work, I will be able to write code like this :

Hi Marc,

I’d try to keep it simple:

class A  
def initialize(param\_a, param\_b, options = {})  
@x = options[:x] || 50 # defaults to 50 if not specified  
@y = options[:y] || 100  
@z = options[:z] || ‘red’  
puts “Initialized with #{@x}/#{@y}/#{@z}”  
end  
end

a = A.new(“hello”, “world”, :x =\> 10, :y =\> 20, :z =\> “red”)  
Initialized with 10/20/red

a = A.new(“hello”, “world”, :z =\> “red”, :y =\> 20, :x =\> 10)  
Initialized with 10/20/red

a = A.new(“hello”, “world”, :z =\> “red”)  
Initialized with 50/100/red

a = A.new(“hello”, “world”, :x =\> 10)  
Initialized with 10/100/red

- Martin

---

<div class="post-metadata">

**Author:** ![kingkadelfek](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/8edcca/32.png) [@kingkadelfek](https://www.ruby-forum.com/u/kingkadelfek)\
**Post date:** [September 7, 2009, 10:10am UTC](https://www.ruby-forum.com/t/something-new-attribute-value-thing/174994/7 "2009-09-07T10:10:04Z")

</div>

Martin B. wrote:

> On Sun, 2009-09-06 at 03:06 +0900, Marc-antoine Kruzik wrote:
> 
> > > A.send(:attr\_accessor, key)  
> > > send(“#{key}=”, val)
> > 
> > This solution is what I was looking for.  
> > With a bit of work, I will be able to write code like this :
> 
> Hi Marc,
> 
> I’d try to keep it simple:
> 
> class A  
> def initialize(param\_a, param\_b, options = {})  
> @x = options[:x] || 50 # defaults to 50 if not specified  
> @y = options[:y] || 100  
> @z = options[:z] || ‘red’  
> puts “Initialized with #{@x}/#{@y}/#{@z}”  
> end  
> end

Use default values is a goog idea. The problem is, you have to write the  
code for @x, @y and @z.

My version is now this one :

I have three classes :  
GUI\_Object \> GUI\_Object\_Graphic \> Picture

The purpose of the code is to avoid to write a lot of code when you are  
working on classes like Picture.

(I know, I don’t optimize my code, if you have better solution, it would  
be nice.)

class GUI\_Object

attr\_accessor :parent

@accessors = [:parent]

def initialize(parent=nil, hash=nil)

```
@parent = parent

hash = param_hash_1(parent, hash)
modify_accessor(hash)

```

end

def param\_hash\_1(parent, hash)  
if hash.is\_a?(Hash)  
return hash  
elsif parent.is\_a?(Hash)  
@parent = nil  
return parent  
end  
return nil  
end

def modify\_accessor(hash)  
return if hash == nil  
hash.each do |key, val|  
if self.class.check\_accessor(key) == true  
# Here’s the 7stud function :  
send(“#{key}=”, val)  
else  
raise(“unknown accessor for class #{self.class}: #{key}”)  
end  
end  
end

def self.check\_accessor(acc)  
if self.accessor != nil and self.accessor.include?(acc)  
return true  
else  
if self != GUI\_Object  
return true if self.ancestors[1].check\_accessor(acc) == true  
end  
end  
return false  
end

def self.accessor  
return @accessors  
end

end

class GUI\_Object\_Graphic \< GUI\_Object

attr\_reader :x  
attr\_reader :y  
attr\_accessor :width  
attr\_accessor :height

@accessors = [:x, :y, :width, :height]

def initialize(parent=nil, x=0, y=0, width=0, height=0, hash=nil)

```
@x = x
@y = y
@width = width
@height = height
hash = param_hash(x, y, width, height, hash)

@x = 0 if @x == nil
@y = 0 if @y == nil
@width = 0 if @width == nil
@height = 0 if @height == nil

super(parent, hash)

```

end

def param\_hash(x, y, width, height, hash)  
if hash.is\_a?(Hash)  
return hash  
elsif x.is\_a?(Hash)  
@x = 0  
return x  
elsif y.is\_a?(Hash)  
@y = 0  
return y  
elsif width.is\_a?(Hash)  
@width = 0  
return width  
elsif height.is\_a?(Hash)  
@height = 0  
return height  
end  
return nil  
end

end

class Picture \< GUI\_Object\_Graphic

attr\_accessor :bg\_color  
attr\_accessor :cadre  
attr\_accessor :marges  
attr\_accessor :image  
attr\_accessor :zoom

# I ONLY have to create THIS list to use the attributes I want

@accessors = [:bg\_color, :picture, :zoom]

# So, it’s really, really not difficult

def initialize(parent=nil, x=0, y=0, width=0, height=0, hash=nil)

```
# Default values
@bg_color = nil
@zoom = 1

super

@marges = [0, 0, 0, 0]
@cadre = nil

```

end

end

So I can use these codes to create a Picture :

x = y = width = height = 0

a = Picture.new(nil, x, y, width, height)  
a = Picture.new(nil, x, y, :zoom =\> 2, :width =\> 30, :bg\_color =\> “red”)

I’m not using a class variable like @@accessors, because of the problems  
with class variables.

With this code, people can easily create new classes like Picture. And  
with a simple list like @accessors = [:bg\_color, :picture, :zoom], they  
can allow to use only the attributes they want.

It’s part of my code to create a super-easy-to-use GUI working with a  
video game graphical library.  
Here’s a screenshot :  
[![](https://i291.photobucket.com/albums/ll318/KingKadelfek/screen05-f95306.png) ](https://i291.photobucket.com/albums/ll318/KingKadelfek/screen05-f95306.png)

I want the users able to create new components (such as Picture), so I  
try to find the most easiest way.
