Mass Assignment on Clas

Hi there,

I am a total newbie to Ruby, so please bare with me.

I want to be able to be able to initialise a Class with a hash. For
instance If I have the class

class Vehicle
attr_accessor :vtype, :description, :vehicle, :capacity
end

I want to be able to do

Vehicle.new(:vtype => ‘ECAR’, :description => ‘Great Car’, :vehicle =>
‘Ford Focus’, :capacity => ‘10’);

Now I could do something like

def initialize(items)
@vtype = items[:vtype]
@description = items[:description]
@vehicle = items[:vehicle]
@capacity = items[:capacity]

puts items.inspect

end

But I was wondering if there was a more generic way of doing this
without specifically defining each variable in initialize? I think
ActiveRecord does something similar!

Many thanks for your assist!

Hi –

On Fri, 28 Aug 2009, Pete M. wrote:

@vehicle = items[:vehicle]
@capacity = items[:capacity]

puts items.inspect

end

But I was wondering if there was a more generic way of doing this
without specifically defining each variable in initialize? I think
ActiveRecord does something similar!

How about:

def initialize(items)
items.each do |key,value|
instance_variable_set("@#{key}", value)
end
end

(possible with some checking to make sure they’re what you want).

David

Pete M. wrote:

Hi there,

I am a total newbie to Ruby, so please bare with me.

I want to be able to be able to initialise a Class with a hash. For
instance If I have the class

class Vehicle
attr_accessor :vtype, :description, :vehicle, :capacity
end

I want to be able to do

Vehicle.new(:vtype => ‘ECAR’, :description => ‘Great Car’, :vehicle =>
‘Ford Focus’, :capacity => ‘10’);

Now I could do something like

def initialize(items)
@vtype = items[:vtype]
@description = items[:description]
@vehicle = items[:vehicle]
@capacity = items[:capacity]

puts items.inspect

end

But I was wondering if there was a more generic way of doing this
without specifically defining each variable in initialize? I think
ActiveRecord does something similar!

Many thanks for your assist!

class X

attr_reader :vtype, :description

def initialize(items)
self.vtype = items[:vtype]
self.description = items[:description]
end

def vtype=(val)
if [“Ecar”, “Fcar”, “Gcar”].include? val
@vtype = val
else
puts “Error”
@vtype = nil
end
end

def description=(descr)
if descr.length > 20
puts “Error”
else
@description = descr
end
end
end

x = X.new(:vtype => “Ecar”, :description => “Great Car”)
puts x.vtype
puts x.description

On Fri, Aug 28, 2009 at 10:06 AM, Rick DeNatale[email protected]
wrote:

Another thing variation would be to use those accessors so as to not
add ‘accidental’ instance variables

Why do I always see typos just AFTER I hit send??? s/thing //


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

Hi –

On Fri, 28 Aug 2009, Rick DeNatale wrote:

On Fri, Aug 28, 2009 at 10:06 AM, Rick DeNatale[email protected] wrote:

Another thing variation would be to use those accessors so as to not
add ‘accidental’ instance variables

Why do I always see typos just AFTER I hit send??? s/thing //

Run your code through Ruby and you’ll see another :slight_smile:

David

On Fri, Aug 28, 2009 at 7:03 AM, Pete M.[email protected] wrote:

I am a total newbie to Ruby, so please bare with me.

Averting my eyes, I’d prefer to keep my clothes on myself! In other
words I’ll grin and BEAR it!

Seriously, David Black already gave you pretty much the response I
would have, although my first steps in refining it a bit might be to
make the hash arg optional:

def initialize(items={}
items.each do |key,value|
instance_variable_set(“@#{key}”, value)
end
end

Another thing variation would be to use those accessors so as to not
add ‘accidental’ instance variables

def initialize(items={}
items.each do |key,value|
send(“#{key}=”, value) rescue raise “unknown attribute #{key}”
end
end

And as the King of Siam said, etcetera, etcetera, etcetera!


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

David A. Black wrote:

Hi –

On Fri, 28 Aug 2009, Rick DeNatale wrote:

On Fri, Aug 28, 2009 at 10:06 AM, Rick DeNatale[email protected] wrote:

Another thing variation would be to use those accessors so as to not
add ‘accidental’ instance variables

Why do I always see typos just AFTER I hit send??? s/thing //

Run your code through Ruby and you’ll see another :slight_smile:

David

Thanks for your responses - much appreciated!

Is this the David A. Black who wrote Ruby for Rails? if so wow a real
honour! I recently finished your book (and enjoyed it).

Coming from a Perl backgrounds its been interesting getting up to speed
with Ruby/Rails although I think I am just at the beginning of the
journey… so much to learn!

Pete M. wrote:

Is this the David A. Black who wrote Ruby for Rails? if so wow a real
honour! I recently finished your book (and enjoyed it).

Yes, as well as the recently published “The Well Grounded Rubyist”.

Hi –

On Fri, 28 Aug 2009, Pete M. wrote:

Run your code through Ruby and you’ll see another :slight_smile:

David

Thanks for your responses - much appreciated!

Is this the David A. Black who wrote Ruby for Rails? if so wow a real
honour! I recently finished your book (and enjoyed it).

The hono(u)r is all mine :slight_smile: I’m glad you liked the book. It has been,
to use the only word I’ve been able to think of to describe the
process, “repurposed” into a just-Ruby book, The Well-Grounded
Rubyist, which you might also like.

Coming from a Perl backgrounds its been interesting getting up to speed
with Ruby/Rails although I think I am just at the beginning of the
journey… so much to learn!

I’m not at the beginning of the journey but after the beginning it’s
all middle – so I’m somewhere in the middle, and enjoying it greatly.

David


David A. Black / Ruby Power and Light, LLC / http://www.rubypal.com
Ruby/Rails training, mentoring, consulting, code-review
Latest book: The Well-Grounded Rubyist (The Well-Grounded Rubyist)

September Ruby training in NJ has been POSTPONED. Details to follow.

On Fri, Aug 28, 2009 at 10:13 AM, David A. Black[email protected]
wrote:

Why do I always see typos just AFTER I hit send??? s/thing //

Run your code through Ruby and you’ll see another :slight_smile:

Actually two.

Balancing parentheses is the hobgoblin of little minds!


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

On Fri, Aug 28, 2009 at 6:03 AM, Pete M.[email protected] wrote:

@vehicle = items[:vehicle]
@capacity = items[:capacity]

puts items.inspect

end

But I was wondering if there was a more generic way of doing this
without specifically defining each variable in initialize? I think
ActiveRecord does something similar!

Many thanks for your assist!

Just playing devil’s advocate, what about using OpenStruct?

require ‘ostruct’

class Vehicle < OpenStruct

end

v1 = Vehicle.new(:vtype => ‘ECAR’, :description => ‘Great Car’, :vehicle
=>
‘Ford Focus’, :capacity => ‘10’)

I guess the concern would be the possibility of adding additional
accessors. Using attr_accessor inside the class seems to keep me from
updating the variables.