Create object by reflection

My doubt is how create objects by reflection, when they need more than
one argument. Given that I need to create them based on array.

def build(instance,clazz,args)
if args == nil
@instances[instance] = Object.const_get(clazz).new
else
@instances[instance] = Object.const_get(clazz).new(args[0])
end
end

And how about to

build “int0”,“Person”,[“name”,]

Since the Person is:

class Person
attr_accessor :name, :surname
def initialize(name,surname)
@name = name
@surname = surname
end
end


leandro moreira - leandromoreira.com.br

xxx

leandro moreira wrote in post #1012318:

My doubt is how create objects by reflection, when they need more than
one argument. Given that I need to create them based on array.

def build(instance,clazz,args)
if args == nil
@instances[instance] = Object.const_get(clazz).new
else
@instances[instance] = Object.const_get(clazz).new(args[0])
end
end

If args is an array:

def build(instance,clazz,args)
@instances[instance] = Object.const_get(clazz).new(*args)
end

Or if you want to call ‘build’ with a variable number of args:

def build(instance,clazz,*args)
@instances[instance] = Object.const_get(clazz).new(*args)
end

7stud – wrote in post #1012360:

Brian C. wrote in post #1012354:

Or if you want to call ‘build’ with a variable number of args:

def build(instance,clazz,*args)
@instances[instance] = Object.const_get(clazz).new(*args)
end

`initialize’: wrong number of arguments (3 for 2) (ArgumentError)

`initialize’: wrong number of arguments (1 for 2) (ArgumentError)

Show your exact code. I would guess that you are passing an array of 3
elements for args, when your class’s initialize method takes only two.

Here’s how it works:

class Foo
def initialize(a,b)
@a, @b = a, b
end
end
=> nil

args = [“foo”, “bar”]
=> [“foo”, “bar”]

Foo.new(*args)
=> #<Foo:0x7f0223609470 @a=“foo”, @b=“bar”>

Cool, thanks you all! =D

Brian C. wrote in post #1012354:

Or if you want to call ‘build’ with a variable number of args:

def build(instance,clazz,*args)
@instances[instance] = Object.const_get(clazz).new(*args)
end

`initialize’: wrong number of arguments (3 for 2) (ArgumentError)

`initialize’: wrong number of arguments (1 for 2) (ArgumentError)

I solved, stupid typo.

:wink:

It’s not working. Suppose I have the builder and RSpec and I tried to
use the approach but both tests failed (String fails because it can’t
convert array to String, and second because wrong number of arguments (1
for 2)

I’m using ruby 1.9.1(1.9.2b)

class Make
attr_accessor :instances
def initialize
@instances = {}
end
def build(instance,clazz,*args)
if args == nil
@instances[instance] = Object.const_get(clazz).new
else
@instances[instance] = Object.const_get(clazz).new(args)
end
end
end

And it’s RSpec

describe Make do
before(:all) do
@make = Make.new
end
describe “Make Instruction” do
it “should keep an instance of String” do
created_object = “test”
@make.build “instance01”, “String”,[“test”]
@make.instances[“instance01”].should == created_object
end
it “should keep an instance of Foo” do
@make.build “instance02”, “Foo”,[“one”,“two”]
end
end
end

class Foo
attr_accessor :one, :two
def initialize(one,two)
@one = one
@two = two
end
end

And the ouput from RSpec is:


  1. Failure/Error: @make.build “instance01”, “String”,[“test”]
    TypeError:
    can’t convert Array into String

    ./lib/instructions/make.rb:11:in `initialize’

    ./lib/instructions/make.rb:11:in `new’

    ./lib/instructions/make.rb:11:in `build’

    ./spec/make_spec.rb:11:in `block (3 levels) in <top (required)>’


  2. Failure/Error: def initialize(one,two)
    ArgumentError:
    wrong number of arguments (1 for 2)

    ./spec/make_spec.rb:22:in `initialize’

    ./lib/instructions/make.rb:11:in `new’

    ./lib/instructions/make.rb:11:in `build’

    ./spec/make_spec.rb:15:in `block (3 levels) in <top (required)>’