Forum: Ruby Creating object from hash

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
1f0d0fbccd8f8fc1ab999e8b79faf495?d=identicon&s=25 Davi Barbosa (dmjb)
on 2008-11-06 21:46
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?
D68c97e8e2f1653b54c24493caf236ae?d=identicon&s=25 Stephen Celis (Guest)
on 2008-11-06 23:07
(Received via mailing list)
Hi,

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

>  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 ...

> 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
E0d864d9677f3c1482a20152b7cac0e2?d=identicon&s=25 Robert Klemme (Guest)
on 2008-11-07 00:07
(Received via mailing list)
On 06.11.2008 21:44, Davi Barbosa wrote:
>   end
> 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
1bac2e65d64faf472cf2ebc94f0f5ee0?d=identicon&s=25 Ara Howard (ahoward)
on 2008-11-07 00:19
(Received via mailing list)
On Nov 6, 2008, at 4:03 PM, Robert Klemme wrote:

>>    end
>> Computer.new({'id' > 1})" does not create the reader for @id and
> irb(main):001:0> Comp = Struct.new :id do
>
> 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://codeforpeople.com/
This topic is locked and can not be replied to.