How create a class instance from class name string

I define a class as follows:

class Tax_factory

def get_tax_by_category(category)

tax_class_name = "#{category}_tax"

# Method_1
#tax_class = Object.const_set(tax_class_name, Class.new)

# Method_2
#tax = eval("#{tax_class_name}")

# Method_3
tax = 'Base_tax'.constantize.new

puts tax.getRate

end

end

I want to get the class instance by its name, such as I input the
category:
Base
it should find the class whose name is ‘Base_tax’, then create a
instance,
and I can use the instance, such as i can invoke the method:
tax.getRate
I try almost every methods, however, no can implement. Some methods just
create a class without methods, that is not what i want.

thanks.

klass = Object.const_get(“String”)
obj = klass.new

Note that if your classes are within modules, you’ll need to find the
outer module first:

module Foo
class Bar; end
end

#klass = Object.const_get(“Foo::Bar”) # doesn’t work
klass = Foo.const_get(“Bar”) # this is fine
obj = klass.new

Or a more dynamic solution:

name = “Foo::Bar”
klass = name.split("::").inject(Object) { |k,n| k.const_get(n) }

li shoubo wrote in post #1010066:

I want to get the class instance by its name, such as I input the
category:
Base
it should find the class whose name is ‘Base_tax’, then create a
instance,
and I can use the instance, such as i can invoke the method:
tax.getRate

tax_class_name = “#{category}_tax”
#tax_class = Object.const_set(tax_class_name, Class.new)
#tax = eval("#{tax_class_name}")

hi Li,

i’m a bit confused by a few things, including whether
“tax_class_name”, “tax_class”, and “tax” represent different ways of
trying the same thing or if they’re different, and where you want
#getRate defined - but maybe something like this helps?

class TaxFactory
def initialize(category)
tax = Object::const_get("#{category}Tax").new
self.get_rate(tax)
end

def get_rate(tax)
puts “#{tax.class} rate is #{tax.rate}%”
end

end

class BaseTax
attr_reader :rate
def initialize
@rate = 5
end
end

class LuxuryTax
attr_reader :rate
def initialize
@rate = 12
end
end

base = TaxFactory.new(“Base”)
lux = TaxFactory.new(“Luxury”)

=> BaseTax rate is 5%
=> LuxuryTax rate is 12%

  • j

Brian C. wrote in post #1010075:

klass = Object.const_get(“String”)
obj = klass.new

Note that if your classes are within modules, you’ll need to find the
outer module first:

module Foo
class Bar; end
end

#klass = Object.const_get(“Foo::Bar”) # doesn’t work
klass = Foo.const_get(“Bar”) # this is fine
obj = klass.new

Or a more dynamic solution:

name = “Foo::Bar”
klass = name.split("::").inject(Object) { |k,n| k.const_get(n) }

Hello,
Thank you for your advice,however, i do not use Module, so i can not
use ,such like Foo::Bar.

jake kaiden wrote in post #1010103:

hi Li,

i’m a bit confused by a few things, including whether
“tax_class_name”, “tax_class”, and “tax” represent different ways of
trying the same thing or if they’re different, and where you want
#getRate defined - but maybe something like this helps?

class TaxFactory
def initialize(category)
tax = Object::const_get("#{category}Tax").new
self.get_rate(tax)
end

def get_rate(tax)
puts “#{tax.class} rate is #{tax.rate}%”
end

end

class BaseTax
attr_reader :rate
def initialize
@rate = 5
end
end

class LuxuryTax
attr_reader :rate
def initialize
@rate = 12
end
end

base = TaxFactory.new(“Base”)
lux = TaxFactory.new(“Luxury”)

=> BaseTax rate is 5%
=> LuxuryTax rate is 12%

  • j

Thanks, yes, what i want to write is like your code. But when i copy
your code, run on my computer, there is an error:

taxFactory.rb:5:in `const_get’: uninitialized constant BaseTax
(NameError)

This error has happened when i use other methods. I use ruby 1.9.2

What do you get when you run the following program:

obj = Object.const_get(“Dog”)

li shoubo wrote in post #1010210:

OK, i use const_get as follows:

def initialize()

tax_class = Object.const_get("BaseTax")
tax = tax_class.new
tax.getRate

end

When I run your code above, I get:

ruby.rb:1: warning: redefining Object#initialize may cause infinite loop

7stud – wrote in post #1010199:

What do you get when you run the following program:

obj = Object.const_get(“Dog”)

OK, i use const_get as follows:

def initialize()

tax_class = Object.const_get("BaseTax")
tax = tax_class.new
tax.getRate

end

getRate is a mothod in BaseTax. The error is:

in `const_get’: uninitialized constant BaseTax (NameError)

Thanks

OK, i solve the problem. i am newer to ruby, so i donot know about ruby
deeply.

i use seperate files to write two class,

in taxFactory.rb, i require the baseTax like this:

require ‘baseTax’

however, it dose not work.

That is because i use ruby 1.9.2

so i change to

require_relative ‘baseTax’

it works out.

what is more, baseTax.rb is for BaseTax class, which is in the same
directory as taxFactory.rb

Thanks all of you!

When I run your code above, I get:

ruby.rb:1: warning: redefining Object#initialize may cause infinite loop

i give you the complete code:

class TaxFactory

def initialize(category)
tax_class_name = “#{category}Tax”
tax_class = Object.const_get(tax_class_name)
tax = tax_class.new
puts tax.rate
end

end

class BaseTax
attr_reader :rate
def initialize
@rate = 0.10
end
end

taxFactory = TaxFactory.new(“Base”)

I got the error:
taxFactory.rb:5:in `const_get’: uninitialized constant BaseTax
(NameError)

my ruby is 1.9.2