[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Creating objects from strings.

Bill

6/5/2005 1:01:00 PM

Hi,

I'm a Java programmer that is trying to learn Ruby.

I'm trying to write a container that creates objects on the fly from a
descriptor. In Java I'd simply do
Class.forName("MyClass").newInstance();

Is there an easy way to do this in Ruby? I basically want a loader
that I can call Loader.createObject(filename, classname) where filename
is the name of the ruby file containing the class and classname is the
actual class.

Also, since I'll be creating more than one instance of each class, how
do I store the class instance?

TIA.

Bill.

8 Answers

Jim Marshall

6/5/2005 1:51:00 PM

0

On 2005-06-05, Bill <ruby@thebackfamily.com> wrote:
> Hi,
>
> I'm a Java programmer that is trying to learn Ruby.
>
> I'm trying to write a container that creates objects on the fly from a
> descriptor. In Java I'd simply do
> Class.forName("MyClass").newInstance();
>
One way is like:
Object.const_get("MyClass").new # returns an instance of MyClass
Or, if your classes are inside a module (say, "MyModule"), then
MyModule.const_get("MyClass").new
> Is there an easy way to do this in Ruby? I basically want a loader
> that I can call Loader.createObject(filename, classname) where filename
> is the name of the ruby file containing the class and classname is the
> actual class.
>
> Also, since I'll be creating more than one instance of each class, how
> do I store the class instance?
>
klass = Object.const_get("MyClass") # Returns the class MyClass
obj = klass.new # Returns an instance of MyClass

There are probably other ways to do these things, but this is the one
I'm familiar with.

james_b

6/5/2005 1:52:00 PM

0

Bill wrote:
> Hi,
>
> I'm a Java programmer that is trying to learn Ruby.
>
> I'm trying to write a container that creates objects on the fly from a
> descriptor. In Java I'd simply do Class.forName("MyClass").newInstance();


mc = Object.const_get( "MyClass" ).new

This presumes that the code already knows about the class MyClass (e.g.,
because the class is defined in the same file, or defined in a file that
has already been read using 'require' or 'load').



BTW, I looked at the Ruby FAQ, and this question doesn't seem to be in
there, despite its popularity.

http://dev.rubycentra...



James
--

http://www.ru... - The Ruby Documentation Site
http://www.r... - News, Articles, and Listings for Ruby & XML
http://www.rub... - The Ruby Store for Ruby Stuff
http://www.jame... - Playing with Better Toys


ES

6/5/2005 1:57:00 PM

0


Le 5/6/2005, "Bill" <ruby@thebackfamily.com> a écrit:
>Hi,
>
>I'm a Java programmer that is trying to learn Ruby.
>
>I'm trying to write a container that creates objects on the fly from a
>descriptor. In Java I'd simply do
>Class.forName("MyClass").newInstance();
>
>Is there an easy way to do this in Ruby? I basically want a loader
>that I can call Loader.createObject(filename, classname) where filename
>is the name of the ruby file containing the class and classname is the
>actual class.
>
>Also, since I'll be creating more than one instance of each class, how
>do I store the class instance?

You can always eval: obj = eval(classname).new, but this is cleaner:

cls = const_get classname
obj = cls.new

If you know the class is in some namespace (or other module):

cls = ModuleName.const_get classname

>TIA.
>
>Bill.

E

--
template<typename duck>
void quack(duck& d) { d.quack(); }


dblack

6/5/2005 2:10:00 PM

0

james_b

6/5/2005 3:48:00 PM

0

David A. Black wrote:
> Hi --
>
> On Sun, 5 Jun 2005, James Britt wrote:
>
>> BTW, I looked at the Ruby FAQ, and this question doesn't seem to be
>> in there, despite its popularity.
>>
>> http://dev.rubycentra...
>
>
> That's an old address; the currently maintained FAQ is at:
>
> http://www.rubygard...
>
> I think Dave T. revised some links to point to that, but I guess the
> old URL still goes to the older FAQ.

The FAQ I looked at is the first one that Google finds. Perhaps that
page could be replaced with one that redirects to the current FAQ.


James


Bill

6/5/2005 5:15:00 PM

0

On 2005-06-05 09:51:42 -0400, James Britt <james_b@neurogami.com> said:

> Bill wrote:
>> Hi,
>>
>> I'm a Java programmer that is trying to learn Ruby.
>>
>> I'm trying to write a container that creates objects on the fly from a
>> descriptor. In Java I'd simply do
>> Class.forName("MyClass").newInstance();
>
>
> mc = Object.const_get( "MyClass" ).new
>
> This presumes that the code already knows about the class MyClass
> (e.g., because the class is defined in the same file, or defined in a
> file that has already been read using 'require' or 'load').
>
>
>
> BTW, I looked at the Ruby FAQ, and this question doesn't seem to be in
> there, despite its popularity.
>
> http://dev.rubycentra...
>
>
>
> James

Thanks for all the quick help. The presumption was my problem. I had
some code that I got that should have worked, but wasn't requiring the
file. I'm now able to create classes from external files/modules with
the following.

def load (filename, classname)

require filename

# taken from http://www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby...
names = classname.split /::/
names.reverse!
unf = Object
unf = unf.const_get(names.pop) while names.length > 0
unf.new
end

load ("myfile.rb", "myModule::myClass")

Nicholas Seckar

6/5/2005 5:35:00 PM

0

Bill wrote:

>
> def load (filename, classname)
>
> require filename
>
> # taken from
> http://www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby...
> names = classname.split /::/
> names.reverse!
> unf = Object
> unf = unf.const_get(names.pop) while names.length > 0
> unf.new
> end
>
> load ("myfile.rb", "myModule::myClass")
>

This is an excellent place to use inject:

def load(filename, classname)
require filename
classname.split('::').inject(Object) {|module, name| module.const_get
name}.new
end

You might also like to know that const_get will look in the parent
modules as well. For example,

module A
module B
end
end

A.constants #=> ['B']
A.const_get :Object #=> Object
A::Object #=> Unitialized constant A::Object

Because of this I've resorted to using eval "#{module}::#{name}" -- Does
anyone know of a non-eval way of doing this?

And, as you may or may not know, Ruby comes with a load method, so you
might want to change your method name to load_instance or something.



Ara.T.Howard

6/5/2005 7:51:00 PM

0