Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can one set property values when initializing an object in Ruby?

Tags:

ruby

Given the following class:

class Test
  attr_accessor :name
end

When I create the object, I want to do the following:

t = Test.new {name = 'Some Test Object'}

At the moment, it results in the name attribute still being nil.

Is that possible without adding an initializer?

like image 276
Ben Hall Avatar asked Feb 27 '10 19:02

Ben Hall


People also ask

How do you initialize a variable in Ruby?

Global variables start with dollar sign like. For Instance Variables: Instance variables can be initialized with @ symbol and the default value for it will be nil.

How do you initialize the value of an object?

Objects can be initialized using new Object() , Object. create() , or using the literal notation (initializer notation). An object initializer is a comma-delimited list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ( {} ).

What is the initialize method in Ruby?

The initialize method is part of the object-creation process in Ruby and it allows us to set the initial values for an object. Below are some points about Initialize : We can define default argument. It will always return a new object so return keyword is not used inside initialize method.

How do you instantiate an object in Ruby?

An object instance is created from a class through the process called instantiation. In Ruby this takes place through the Class method new . This function sets up the object in memory and then delegates control to the initialize function of the class if it is present.


2 Answers

ok,

I came up with a solution. It uses the initialize method but on the other hand do exactly what you want.

class Test
  attr_accessor :name

  def initialize(init)
    init.each_pair do |key, val|
      instance_variable_set('@' + key.to_s, val)
    end
  end

  def display
    puts @name
  end

end

t = Test.new :name => 'hello'
t.display

happy ? :)


Alternative solution using inheritance. Note, with this solution, you don't need to explicitly declare the attr_accessor!

class CSharpStyle
  def initialize(init)
    init.each_pair do |key, val|
      instance_variable_set('@' + key.to_s, val)
      instance_eval "class << self; attr_accessor :#{key.to_s}; end"
    end
  end
end

class Test < CSharpStyle
  def initialize(arg1, arg2, *init)
    super(init.last)
  end
end

t = Test.new 'a val 1', 'a val 2', {:left => 'gauche', :right => 'droite'}
puts "#{t.left} <=> #{t.right}"
like image 196
Nicolas Guillaume Avatar answered Sep 23 '22 03:09

Nicolas Guillaume


As mentioned by others, the easiest way to do this would be to define an initialize method. If you don't want to do that, you could make your class inherit from Struct.

class Test < Struct.new(:name)
end

So now:

>> t = Test.new("Some Test Object")
=> #<struct Test name="Some Test Object">
>> t.name
=> "Some Test Object"
like image 32
ry. Avatar answered Sep 25 '22 03:09

ry.