[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Creating object from hash

Davi Barbosa

11/6/2008 8:44:00 PM

I'm creating an object from a hash using this:

class Computer
def initialize(hash)
hash.each do |k,v|
instance_variable_set("@#{k}", v) ## create and initialize an
instance variable for this key/value pair
instance_eval %Q{ class << self ; attr_reader #{k.intern.inspect}
; end }
end
end
end

This works fine except if I need to define a method with the same name
of a key (if I need an complicated getter/setter for example). So I
added a test to attr_reader line:
instance_eval %Q{ class << self ; attr_reader #{k.intern.inspect} ; end
} if !instance_eval %Q{defined? #{k}}

As an Object, some methods are defined (like "id"). So "pc =
Computer.new({'id' > 1})" does not create the reader for @id and "pc.id"
calls some unwanted method.

If I just add "attr_reader :id" everything works. Can I do it directly,
without adding attr_reader (or attr_accessor) every time that I get an
error?
--
Posted via http://www.ruby-....

3 Answers

Stephen Celis

11/6/2008 10:05:00 PM

0

Hi,

On Nov 6, 2008, at 2:44 PM, Davi Barbosa wrote:

> I'm creating an object from a hash using this:
>
> class Computer
> def initialize(hash)
> hash.each do |k,v|
> instance_variable_set("@#{k}", v) ## create and initialize an
> instance variable for this key/value pair
> instance_eval %Q{ class << self ; attr_reader #{k.intern.inspect}
> ; end }
> end
> end
> end

Just wondering if you've looked at OpenStruct?

% ri OpenStruct

You can achieve the above more simply.

require 'ostruct'
Computer = Class.new(OpenStruct) # or class Computer < OpenStruct ...

> This works fine except if I need to define a method with the same name
> of a key (if I need an complicated getter/setter for example). So I
> added a test to attr_reader line:
> instance_eval %Q{ class << self ; attr_reader #{k.intern.inspect} ;
> end
> } if !instance_eval %Q{defined? #{k}}
>
> As an Object, some methods are defined (like "id"). So "pc =
> Computer.new({'id' > 1})" does not create the reader for @id and
> "pc.id"
> calls some unwanted method.

"id" is technically deprecated. Even so, it's also available at
Object#__id__ and Object#object_id.

But still, you can undefine methods:

% ri Module#undef_method

> If I just add "attr_reader :id" everything works. Can I do it
> directly,
> without adding attr_reader (or attr_accessor) every time that I get an
> error?

Try some of the things I've mentioned above?

Best,
Stephen

Robert Klemme

11/6/2008 11:03:00 PM

0

On 06.11.2008 21:44, Davi Barbosa wrote:
> I'm creating an object from a hash using this:
>
> class Computer
> def initialize(hash)
> hash.each do |k,v|
> instance_variable_set("@#{k}", v) ## create and initialize an
> instance variable for this key/value pair
> instance_eval %Q{ class << self ; attr_reader #{k.intern.inspect}
> ; end }
> end
> end
> end
>
> This works fine except if I need to define a method with the same name
> of a key (if I need an complicated getter/setter for example). So I
> added a test to attr_reader line:
> instance_eval %Q{ class << self ; attr_reader #{k.intern.inspect} ; end
> } if !instance_eval %Q{defined? #{k}}
>
> As an Object, some methods are defined (like "id"). So "pc =
> Computer.new({'id' > 1})" does not create the reader for @id and "pc.id"
> calls some unwanted method.
>
> If I just add "attr_reader :id" everything works. Can I do it directly,
> without adding attr_reader (or attr_accessor) every time that I get an
> error?

You can make your life easier with Struct:

irb(main):001:0> Comp = Struct.new :id do
irb(main):002:1* def initialize(h)
irb(main):003:2> members.each {|m| self[m] = h[m] || h[m.to_sym]}
irb(main):004:2> end
irb(main):005:1> end
=> Comp
irb(main):006:0> c = Comp.new(:id=>133)
=> #<struct Comp id=133>
irb(main):007:0> d = Comp.new("id"=>133)
=> #<struct Comp id=133>
irb(main):008:0>

Kind regards

robert

ara.t.howard

11/6/2008 11:17:00 PM

0


On Nov 6, 2008, at 4:03 PM, Robert Klemme wrote:

> On 06.11.2008 21:44, Davi Barbosa wrote:
>> I'm creating an object from a hash using this:
>> class Computer
>> def initialize(hash)
>> hash.each do |k,v|
>> instance_variable_set("@#{k}", v) ## create and initialize an
>> instance variable for this key/value pair
>> instance_eval %Q{ class << self ; attr_reader
>> #{k.intern.inspect}
>> ; end }
>> end
>> end
>> end
>> This works fine except if I need to define a method with the same
>> name
>> of a key (if I need an complicated getter/setter for example). So I
>> added a test to attr_reader line:
>> instance_eval %Q{ class << self ; attr_reader #{k.intern.inspect} ;
>> end
>> } if !instance_eval %Q{defined? #{k}}
>> As an Object, some methods are defined (like "id"). So "pc =
>> Computer.new({'id' > 1})" does not create the reader for @id and
>> "pc.id"
>> calls some unwanted method.
>> If I just add "attr_reader :id" everything works. Can I do it
>> directly,
>> without adding attr_reader (or attr_accessor) every time that I get
>> an
>> error?
>
> You can make your life easier with Struct:
>
> irb(main):001:0> Comp = Struct.new :id do
> irb(main):002:1* def initialize(h)
> irb(main):003:2> members.each {|m| self[m] = h[m] || h[m.to_sym]}
> irb(main):004:2> end
> irb(main):005:1> end
> => Comp
> irb(main):006:0> c = Comp.new(:id=>133)
> => #<struct Comp id=133>
> irb(main):007:0> d = Comp.new("id"=>133)
> => #<struct Comp id=133>
> irb(main):008:0>
>
> Kind regards
>
> robert
>

and even easier with fattr


class Computer
fattr :foo
fattr :bar

def initialize options = {}
options.each{|k,v| send k, v}
end
end

a @ http://codeforp...
--
we can deny everything, except that we have the possibility of being
better. simply reflect on that.
h.h. the 14th dalai lama