[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Anything better than klass = eval("#{task_class}"

Paganoni

4/1/2009 1:12:00 PM

Hi, well subject is self explanatory...

Seems a bit to verbose for me but I don't know any other solution to
convert a string containing a class name to a constant of that class
name... Excepted rails way : task_class.camelize.constantize which is
verbose too...
9 Answers

Gregory Brown

4/1/2009 1:33:00 PM

0

On Wed, Apr 1, 2009 at 9:14 AM, Paganoni <noway@fakenullvoid.com> wrote:
> Hi, well subject is self explanatory...
>
> Seems a bit to verbose for me but I don't know any other solution to convert
> a string containing a class name to a constant of that class name...
> Excepted rails way : task_class.camelize.constantize which is verbose too...

>> Object.const_get("String")
=> String

-greg

--
BOOK: http://rubybestpra...
TECH: http://blog.majesticseacr...
NON-TECH: http://metametta.bl...

Rob Biedenharn

4/1/2009 2:47:00 PM

0

On Apr 1, 2009, at 9:32 AM, Gregory Brown wrote:

> On Wed, Apr 1, 2009 at 9:14 AM, Paganoni <noway@fakenullvoid.com>
> wrote:
>> Hi, well subject is self explanatory...
>>
>> Seems a bit to verbose for me but I don't know any other solution
>> to convert
>> a string containing a class name to a constant of that class name...
>> Excepted rails way : task_class.camelize.constantize which is
>> verbose too...
>
>>> Object.const_get("String")
> => String
>
> -greg
>
> --
> BOOK: http://rubybestpra...
> TECH: http://blog.majesticseacr...
> NON-TECH: http://metametta.bl...

Or dealing with things like Admin::User or Net::HTTP

# from Jim Weirich (based on email correspondence)
def constantize(camel_cased_word)
camel_cased_word.
sub(/^::/,'').
split("::").
inject(Object) { |scope, name| scope.const_get(name) }
end

It may be more verbose, but it is much safer that plain 'ole eval()

-Rob

Rob Biedenharn http://agileconsult...
Rob@AgileConsultingLLC.com

Rick DeNatale

4/1/2009 4:09:00 PM

0

[Note: parts of this message were removed to make it a legal post.]

On Wed, Apr 1, 2009 at 10:47 AM, Rob Biedenharn
<Rob@agileconsultingllc.com>wrote:

> On Apr 1, 2009, at 9:32 AM, Gregory Brown wrote:
>
> On Wed, Apr 1, 2009 at 9:14 AM, Paganoni <noway@fakenullvoid.com> wrote:
>>
>>> Hi, well subject is self explanatory...
>>>
>>> Seems a bit to verbose for me but I don't know any other solution to
>>> convert
>>> a string containing a class name to a constant of that class name...
>>> Excepted rails way : task_class.camelize.constantize which is verbose
>>> too...
>>>
>>
>> Object.const_get("String")
>>>>
>>> => String
>>
>> -greg
>>
>> --
>> BOOK: http://rubybestpra...
>> TECH: http://blog.majesticseacr...
>> NON-TECH: http://metametta.bl...
>>
>
> Or dealing with things like Admin::User or Net::HTTP
>
> # from Jim Weirich (based on email correspondence)
> def constantize(camel_cased_word)
> camel_cased_word.
> sub(/^::/,'').
> split("::").
> inject(Object) { |scope, name| scope.const_get(name) }
> end
>
> It may be more verbose, but it is much safer that plain 'ole eval()
>

Actually, I don't think this is entirely right, since const_get will find
constants found in outer scopes.

For example constantize("MyModule::Object") would return ::Object

So a little better would be:

def constantize(camel_cased_word)
camel_cased_word.
sub(/^::/,'').
split("::").
inject(Object) { |scope, name| scope.const_defined?(name) ?
scope.const_get(name) : scope.const_missing(name) }
end



--
Rick DeNatale

Blog: http://talklikeaduck.denh...
Twitter: http://twitter.com/Ri...
WWR: http://www.workingwithrails.com/person/9021-ric...
LinkedIn: http://www.linkedin.com/in/ri...

Sean O'Halpin

4/1/2009 4:31:00 PM

0

On Wed, Apr 1, 2009 at 5:09 PM, Rick DeNatale <rick.denatale@gmail.com> wro=
te:
>
> Actually, I don't think this is entirely right, since const_get will find
> constants found in outer scopes.
>
> For example constantize("MyModule::Object") would return ::Object
>
> So a little better would be:
>
> =A0def constantize(camel_cased_word)
> =A0 camel_cased_word.
> =A0 =A0 sub(/^::/,'').
> =A0 =A0 split("::").
> =A0 =A0 inject(Object) { |scope, name| scope.const_defined?(name) ?
> scope.const_get(name) : scope.const_missing(name) }
> =A0end

The const_missing handling is a nice touch. I'm pinching this :)

Rob Biedenharn

4/1/2009 4:37:00 PM

0


On Apr 1, 2009, at 12:09 PM, Rick DeNatale wrote:

> On Wed, Apr 1, 2009 at 10:47 AM, Rob Biedenharn
> <Rob@agileconsultingllc.com>wrote:
>
>> On Apr 1, 2009, at 9:32 AM, Gregory Brown wrote:
>>
>> On Wed, Apr 1, 2009 at 9:14 AM, Paganoni <noway@fakenullvoid.com>
>> wrote:
>>>
>>>> Hi, well subject is self explanatory...
>>>>
>>>> Seems a bit to verbose for me but I don't know any other solution
>>>> to
>>>> convert
>>>> a string containing a class name to a constant of that class
>>>> name...
>>>> Excepted rails way : task_class.camelize.constantize which is
>>>> verbose
>>>> too...
>>>>
>>>
>>> Object.const_get("String")
>>>>>
>>>> => String
>>>
>>> -greg
>>>
>>> --
>>> BOOK: http://rubybestpra...
>>> TECH: http://blog.majesticseacr...
>>> NON-TECH: http://metametta.bl...
>>>
>>
>> Or dealing with things like Admin::User or Net::HTTP
>>
>> # from Jim Weirich (based on email correspondence)
>> def constantize(camel_cased_word)
>> camel_cased_word.
>> sub(/^::/,'').
>> split("::").
>> inject(Object) { |scope, name| scope.const_get(name) }
>> end
>>
>> It may be more verbose, but it is much safer that plain 'ole eval()
>>
>
> Actually, I don't think this is entirely right, since const_get will
> find
> constants found in outer scopes.
>
> For example constantize("MyModule::Object") would return ::Object
>
> So a little better would be:
>
> def constantize(camel_cased_word)
> camel_cased_word.
> sub(/^::/,'').
> split("::").
> inject(Object) { |scope, name| scope.const_defined?(name) ?
> scope.const_get(name) : scope.const_missing(name) }
> end
>
> --
> Rick DeNatale
>
> Blog: http://talklikeaduck.denh...
> Twitter: http://twitter.com/Ri...
> WWR: http://www.workingwithrails.com/person/9021-ric...
> LinkedIn: http://www.linkedin.com/in/ri...


irb> # from Jim Weirich (based on email correspondence)
?> def constantize(camel_cased_word)
irb> camel_cased_word.
?> sub(/^::/,'').
?> split("::").
?> inject(Object) { |scope, name| scope.const_get(name) }
irb> end
=> nil
irb> constantize("MyModule::Object")
NameError: uninitialized constant MyModule
from (irb):6:in `const_get'
from (irb):6:in `constantize'
from (irb):8:in `inject'
from (irb):3:in `each'
from (irb):3:in `inject'
from (irb):3:in `constantize'
from (irb):8
from :0
irb> def constantize(camel_cased_word)
irb> camel_cased_word.
?> sub(/^::/,'').
?> split("::").
?> inject(Object) { |scope, name| scope.const_defined?
(name) ? scope.const_get(name) : scope.const_missing(name) }
irb> end
=> nil
irb> constantize("MyModule::Object")
NameError: uninitialized constant MyModule
from (irb):14:in `constantize'
from (irb):16:in `inject'
from (irb):11:in `each'
from (irb):11:in `inject'
from (irb):11:in `constantize'
from (irb):16
from :0

Except for the slight difference in the backtrace, it looks the same
to me. Why do you think it will return Object for
constantize("MyModule::Object") ?

-Rob

Rob Biedenharn http://agileconsult...
Rob@AgileConsultingLLC.com


Rick DeNatale

4/1/2009 6:25:00 PM

0

[Note: parts of this message were removed to make it a legal post.]

On Wed, Apr 1, 2009 at 12:37 PM, Rob Biedenharn
<Rob@agileconsultingllc.com>wrote:

>
> On Apr 1, 2009, at 12:09 PM, Rick DeNatale wrote:
>
> On Wed, Apr 1, 2009 at 10:47 AM, Rob Biedenharn
>> <Rob@agileconsultingllc.com>wrote:
>>
>> On Apr 1, 2009, at 9:32 AM, Gregory Brown wrote:
>>>
>>> On Wed, Apr 1, 2009 at 9:14 AM, Paganoni <noway@fakenullvoid.com> wrote:
>>>
>>>>
>>>> Hi, well subject is self explanatory...
>>>>>
>>>>> Seems a bit to verbose for me but I don't know any other solution to
>>>>> convert
>>>>> a string containing a class name to a constant of that class name...
>>>>> Excepted rails way : task_class.camelize.constantize which is verbose
>>>>> too...
>>>>>
>>>>>
>>>> Object.const_get("String")
>>>>
>>>>>
>>>>>> => String
>>>>>
>>>>
>>>> -greg
>>>>
>>>> --
>>>> BOOK: http://rubybestpra...
>>>> TECH: http://blog.majesticseacr...
>>>> NON-TECH: http://metametta.bl...
>>>>
>>>>
>>> Or dealing with things like Admin::User or Net::HTTP
>>>
>>> # from Jim Weirich (based on email correspondence)
>>> def constantize(camel_cased_word)
>>> camel_cased_word.
>>> sub(/^::/,'').
>>> split("::").
>>> inject(Object) { |scope, name| scope.const_get(name) }
>>> end
>>>
>>> It may be more verbose, but it is much safer that plain 'ole eval()
>>>
>>>
>> Actually, I don't think this is entirely right, since const_get will find
>> constants found in outer scopes.
>>
>> For example constantize("MyModule::Object") would return ::Object
>>
>> So a little better would be:
>>
>> def constantize(camel_cased_word)
>> camel_cased_word.
>> sub(/^::/,'').
>> split("::").
>> inject(Object) { |scope, name| scope.const_defined?(name) ?
>> scope.const_get(name) : scope.const_missing(name) }
>> end
>>
>> Except for the slight difference in the backtrace, it looks the same to
> me. Why do you think it will return Object for
> constantize("MyModule::Object") ?


Because it does, if MyModule is actually defined and doesn't define another
inner constant called Object:

def constantize(camel_cased_word)
camel_cased_word.

sub(/^::/,'').
split("::").
inject(Object) { |scope, name| scope.const_get(name) }
end


module MyModule
end

constantize("MyModule::Object") # => Object

Rob Biedenharn

4/1/2009 7:29:00 PM

0


On Apr 1, 2009, at 2:24 PM, Rick DeNatale wrote:

> Because it does, if MyModule is actually defined and doesn't define
> another
> inner constant called Object:


Ah, I see now. Thanks for the improvement, Rick!

-Rob

Rob Biedenharn http://agileconsult...
Rob@AgileConsultingLLC.com


Paganoni

4/2/2009 6:25:00 AM

0

le 01/04/2009 16:47, Rob Biedenharn nous a dit:
> On Apr 1, 2009, at 9:32 AM, Gregory Brown wrote:
>
>> On Wed, Apr 1, 2009 at 9:14 AM, Paganoni <noway@fakenullvoid.com>
>> wrote:
>>> Hi, well subject is self explanatory...
>>>
>>> Seems a bit to verbose for me but I don't know any other solution
>>> to convert
>>> a string containing a class name to a constant of that class name...
>>> Excepted rails way : task_class.camelize.constantize which is
>>> verbose too...
>>>> Object.const_get("String")
>> => String
>>
>
> Or dealing with things like Admin::User or Net::HTTP
>
> # from Jim Weirich (based on email correspondence)
> def constantize(camel_cased_word)
> camel_cased_word.
> sub(/^::/,'').
> split("::").
> inject(Object) { |scope, name| scope.const_get(name) }
> end
>
> It may be more verbose, but it is much safer that plain 'ole eval()
>

Okay, so nothing less verbose ;-) But thanks for all the answers...

Gregory Brown

4/2/2009 2:17:00 PM

0

On Thu, Apr 2, 2009 at 2:30 AM, Paganoni <noway@fakenullvoid.com> wrote:
> le 01/04/2009 16:47, Rob Biedenharn nous a dit:
>>
>> On Apr 1, 2009, at 9:32 AM, Gregory Brown wrote:
>>
>>> On Wed, Apr 1, 2009 at 9:14 AM, Paganoni <noway@fakenullvoid.com> =A0wr=
ote:
>>>>
>>>> Hi, well subject is self explanatory...
>>>>
>>>> Seems a bit to verbose for me but I don't know any other solution =A0t=
o
>>>> convert
>>>> a string containing a class name to a constant of that class name...
>>>> Excepted rails way : task_class.camelize.constantize which is =A0verbo=
se
>>>> too...
>>>>>
>>>>> Object.const_get("String")
>>>
>>> =3D> String
>>>
>>
>> Or dealing with things like Admin::User or Net::HTTP
>>
>> =A0 # from Jim Weirich (based on email correspondence)
>> =A0 def constantize(camel_cased_word)
>> =A0 =A0 camel_cased_word.
>> =A0 =A0 =A0 sub(/^::/,'').
>> =A0 =A0 =A0 split("::").
>> =A0 =A0 =A0 inject(Object) { |scope, name| scope.const_get(name) }
>> =A0 end
>>
>> It may be more verbose, but it is much safer that plain 'ole eval()
>>
>
> Okay, so nothing less verbose ;-) But thanks for all the answers...

But all of the mentioned suggestions are much better than
eval("ConstantName") in security, performance, and general design.
So if you want something less verbose, just make a method like
C("Whatever") that uses one of those implementations, rather than
forcing Ruby to fire up its parser via eval() just to get a constant.