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

Discussion in 'Ruby' started by Paganoni, Apr 1, 2009.

  1. Paganoni

    Paganoni Guest

    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...
    Paganoni, Apr 1, 2009
    #1
    1. Advertising

  2. On Wed, Apr 1, 2009 at 9:14 AM, Paganoni <> 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://rubybestpractices.com
    TECH: http://blog.majesticseacreature.com
    NON-TECH: http://metametta.blogspot.com
    Gregory Brown, Apr 1, 2009
    #2
    1. Advertising

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

    > On Wed, Apr 1, 2009 at 9:14 AM, Paganoni <>
    > 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://rubybestpractices.com
    > TECH: http://blog.majesticseacreature.com
    > NON-TECH: http://metametta.blogspot.com


    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://agileconsultingllc.com
    Rob Biedenharn, Apr 1, 2009
    #3
  4. [Note: parts of this message were removed to make it a legal post.]

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

    > On Apr 1, 2009, at 9:32 AM, Gregory Brown wrote:
    >
    > On Wed, Apr 1, 2009 at 9:14 AM, Paganoni <> 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://rubybestpractices.com
    >> TECH: http://blog.majesticseacreature.com
    >> NON-TECH: http://metametta.blogspot.com
    >>

    >
    > 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.denhaven2.com/
    Twitter: http://twitter.com/RickDeNatale
    WWR: http://www.workingwithrails.com/person/9021-rick-denatale
    LinkedIn: http://www.linkedin.com/in/rickdenatale
    Rick DeNatale, Apr 1, 2009
    #4
  5. On Wed, Apr 1, 2009 at 5:09 PM, Rick DeNatale <> 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 :)
    Sean O'Halpin, Apr 1, 2009
    #5
  6. On Apr 1, 2009, at 12:09 PM, Rick DeNatale wrote:

    > On Wed, Apr 1, 2009 at 10:47 AM, Rob Biedenharn
    > <>wrote:
    >
    >> On Apr 1, 2009, at 9:32 AM, Gregory Brown wrote:
    >>
    >> On Wed, Apr 1, 2009 at 9:14 AM, Paganoni <>
    >> 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://rubybestpractices.com
    >>> TECH: http://blog.majesticseacreature.com
    >>> NON-TECH: http://metametta.blogspot.com
    >>>

    >>
    >> 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.denhaven2.com/
    > Twitter: http://twitter.com/RickDeNatale
    > WWR: http://www.workingwithrails.com/person/9021-rick-denatale
    > LinkedIn: http://www.linkedin.com/in/rickdenatale



    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://agileconsultingllc.com
    Rob Biedenharn, Apr 1, 2009
    #6
  7. [Note: parts of this message were removed to make it a legal post.]

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

    >
    > On Apr 1, 2009, at 12:09 PM, Rick DeNatale wrote:
    >
    > On Wed, Apr 1, 2009 at 10:47 AM, Rob Biedenharn
    >> <>wrote:
    >>
    >> On Apr 1, 2009, at 9:32 AM, Gregory Brown wrote:
    >>>
    >>> On Wed, Apr 1, 2009 at 9:14 AM, Paganoni <> 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://rubybestpractices.com
    >>>> TECH: http://blog.majesticseacreature.com
    >>>> NON-TECH: http://metametta.blogspot.com
    >>>>
    >>>>
    >>> 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
    Rick DeNatale, Apr 1, 2009
    #7
  8. 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://agileconsultingllc.com
    Rob Biedenharn, Apr 1, 2009
    #8
  9. Paganoni

    Paganoni Guest

    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 <>
    >> 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...
    Paganoni, Apr 2, 2009
    #9
  10. On Thu, Apr 2, 2009 at 2:30 AM, Paganoni <> 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 <> =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.
    Gregory Brown, Apr 2, 2009
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Shawn Repphan

    Anything better than Panel control?

    Shawn Repphan, Nov 1, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    368
    Mythran
    Nov 1, 2005
  2. John J. Lee
    Replies:
    12
    Views:
    470
    John J. Lee
    Jun 8, 2005
  3. Peter Bencsik
    Replies:
    2
    Views:
    810
  4. Eric Mahurin

    idea: klass.from_s(str)

    Eric Mahurin, Aug 25, 2005, in forum: Ruby
    Replies:
    8
    Views:
    120
    Nikolai Weibull
    Aug 26, 2005
  5. Replies:
    0
    Views:
    166
Loading...

Share This Page