dynamically named variables or Constants

Discussion in 'Ruby' started by Tom V., May 6, 2007.

  1. Tom V.

    Tom V. Guest

    Hi,

    for each user I need to create and call
    a dynamically named _GLOBAL_ variable (or Constant)
    labeled with the user name.
    To make it clear what I mean:

    # begin "Ruby Pseudocode"
    user_name = "tom"
    $#{user_name}_dyn_var = "/path/to/nirvana"
    # end "Ruby Pseudocode"

    Is there a way to do that?
    How would I call that new variable '$#{user_name}_dyn_var' ?
    I tried "Module::const_set":

    # begin Ruby
    constant_name = "#{user_name.upcase}_VAR"
    constant = self::class::const_set(constant_name, "/path/to/nirvana")
    # end Ruby

    but couldn't find a way to call "#{user_name.upcase}_VAR".

    you may ask why I either need a global var or a Constant:
    I am using the "live_tree" plugin
    from http://www.epiphyte.ca/code/live_tree.html
    to create a file system browser.
    As far as I can tell,
    the plugin requires either a global var or a Constant
    to initialize the file system model.

    If someone has tried this plugin before
    and found another solution, let me know.
    The author is not responding to my mails.

    Thanks for your input,
    Tom.
     
    Tom V., May 6, 2007
    #1
    1. Advertising

  2. Alle domenica 6 maggio 2007, Tom V. ha scritto:
    > Hi,
    >
    > for each user I need to create and call
    > a dynamically named _GLOBAL_ variable (or Constant)
    > labeled with the user name.
    > To make it clear what I mean:
    >
    > # begin "Ruby Pseudocode"
    > user_name = "tom"
    > $#{user_name}_dyn_var = "/path/to/nirvana"
    > # end "Ruby Pseudocode"
    >
    > Is there a way to do that?
    > How would I call that new variable '$#{user_name}_dyn_var' ?
    > I tried "Module::const_set":
    >
    > # begin Ruby
    > constant_name = "#{user_name.upcase}_VAR"
    > constant = self::class::const_set(constant_name, "/path/to/nirvana")
    > # end Ruby
    >
    > but couldn't find a way to call "#{user_name.upcase}_VAR".
    >
    > you may ask why I either need a global var or a Constant:
    > I am using the "live_tree" plugin
    > from http://www.epiphyte.ca/code/live_tree.html
    > to create a file system browser.
    > As far as I can tell,
    > the plugin requires either a global var or a Constant
    > to initialize the file system model.
    >
    > If someone has tried this plugin before
    > and found another solution, let me know.
    > The author is not responding to my mails.
    >
    > Thanks for your input,
    > Tom.


    I'm not sure about what you mean when saying 'a way to
    call "#{user_name.upcase}_VAR". If you mean how to get the value of the
    constant, then you can use const_get, which works like const_set:

    self.class.const_get( constant_name)
    => "/path/to/nirvana"

    I hope this helps

    Stefano
     
    Stefano Crocco, May 6, 2007
    #2
    1. Advertising

  3. Tom V.

    Tom V. Guest

    Hi Stefano,

    thanks for your advice.
    However, when I try to call "self.const_get"
    from another method (but same class), I get an error:

    --> NameError (uninitialized constant MyClass::TOM_VAR)

    Here is how I created 'TOM_VAR' (simplified):

    def xyz_method

    constant_name = "#{@user.name.upcase}_VAR"
    logger.info("#{constant_name}")
    # output: TOM_VAR

    constant = MyClass.const_set(constant_name, "/path/to/nirvana")
    logger.info("#{constant}")
    # output: /path/to/nirvana

    session[:constant_name] = constant_name

    end

    In the following method I get the error:

    def abc_method

    @constant = MyClass.const_get(session[:constant_name])
    # ERROR

    end

    Thanks for helping me out
    Tom.


    On Sun, 6 May 2007 20:21:53 +0900
    Stefano Crocco <> wrote:

    > Alle domenica 6 maggio 2007, Tom V. ha scritto:
    > > Hi,
    > >
    > > for each user I need to create and call
    > > a dynamically named _GLOBAL_ variable (or Constant)
    > > labeled with the user name.
    > > To make it clear what I mean:
    > >
    > > # begin "Ruby Pseudocode"
    > > user_name = "tom"
    > > $#{user_name}_dyn_var = "/path/to/nirvana"
    > > # end "Ruby Pseudocode"
    > >
    > > Is there a way to do that?
    > > How would I call that new variable '$#{user_name}_dyn_var' ?
    > > I tried "Module::const_set":
    > >
    > > # begin Ruby
    > > constant_name = "#{user_name.upcase}_VAR"
    > > constant = self::class::const_set(constant_name, "/path/to/nirvana")
    > > # end Ruby
    > >
    > > but couldn't find a way to call "#{user_name.upcase}_VAR".
    > >
    > > you may ask why I either need a global var or a Constant:
    > > I am using the "live_tree" plugin
    > > from http://www.epiphyte.ca/code/live_tree.html
    > > to create a file system browser.
    > > As far as I can tell,
    > > the plugin requires either a global var or a Constant
    > > to initialize the file system model.
    > >
    > > If someone has tried this plugin before
    > > and found another solution, let me know.
    > > The author is not responding to my mails.
    > >
    > > Thanks for your input,
    > > Tom.

    >
    > I'm not sure about what you mean when saying 'a way to
    > call "#{user_name.upcase}_VAR". If you mean how to get the value of the
    > constant, then you can use const_get, which works like const_set:
    >
    > self.class.const_get( constant_name)
    > => "/path/to/nirvana"
    >
    > I hope this helps
    >
    > Stefano
    >
     
    Tom V., May 6, 2007
    #3
  4. Alle domenica 6 maggio 2007, Tom V. ha scritto:
    > Hi Stefano,
    >
    > thanks for your advice.
    > However, when I try to call "self.const_get"
    > from another method (but same class), I get an error:
    >
    > --> NameError (uninitialized constant MyClass::TOM_VAR)
    >
    > Here is how I created 'TOM_VAR' (simplified):
    >
    > def xyz_method
    >
    > =A0 =A0 constant_name =3D "#{@user.name.upcase}_VAR"
    > =A0 =A0 logger.info("#{constant_name}")
    > =A0 =A0 # output: TOM_VAR
    >
    > =A0 =A0 constant =3D MyClass.const_set(constant_name, "/path/to/nirvana")
    > =A0 =A0 logger.info("#{constant}")
    > =A0 =A0 # output: /path/to/nirvana
    >
    > =A0 =A0 session[:constant_name] =3D constant_name
    >
    > end
    >
    > In the following method I get the error:
    >
    > def abc_method
    >
    > =A0 =A0 @constant =3D MyClass.const_get(session[:constant_name])
    > =A0 =A0 # ERROR
    >
    > end
    >
    > Thanks for helping me out
    > Tom.


    I can't understand why you get an error. I modified your code just a bit (b=
    y=20
    the way, what exactly is session?) to give the two methods some context and=
    =20
    put it in a script:

    class MyClass

    def initialize
    @user =3D 'tom'
    @session =3D {}
    end

    def xyz_method
    =20
    constant_name =3D "#{@user.upcase}_VAR"
    =20
    constant =3D MyClass.const_set(constant_name, "/path/to/nirvana")
    =20
    @session[:constant_name] =3D constant_name
    =20
    end
    =20
    def abc_method
    =20
    @constant =3D MyClass.const_get(@session[:constant_name])
    puts @constant
    =20
    end
    end

    c =3D MyClass.new
    c.xyz_method
    c.abc_method

    This works. Since I don't know anything about rails and the live tree plugi=
    n,=20
    I may have missed something related to them. You can try using=20
    MyClass.constants in the abc_method to get a list of the constants defined=
    =20
    for MyClass; this could give you some hints about what's happening.

    Stefano
     
    Stefano Crocco, May 6, 2007
    #4
  5. Tom V.

    Tom V. Guest

    Hi Stefano,

    it's not working for me.
    MyClass.const_get always returns a NameError.
    Trying:

    MyClass.const_defined?(session[:constant_name])

    always returns 'false'
    (except for the method where constant_name was defined...).

    My guess is that 'session' cannot store Constants created the way I do it.
    However, storing other large and complex objects is not a problem.

    'session' is the standard Rails hash-like collection
    using key/values pairs to store information
    during subsequent requests from the same browser.
    '@session' is deprecated now.

    Thanks for your input.
    Tom.

    My Ruby version is:
    ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-linux]


    On Sun, 6 May 2007 22:05:42 +0900
    Stefano Crocco <> wrote:
    >
    > I can't understand why you get an error. I modified your code just a bit (by
    > the way, what exactly is session?) to give the two methods some context and
    > put it in a script:
    >
    > class MyClass
    >
    > def initialize
    > @user = 'tom'
    > @session = {}
    > end
    >
    > def xyz_method
    >
    > constant_name = "#{@user.upcase}_VAR"
    >
    > constant = MyClass.const_set(constant_name, "/path/to/nirvana")
    >
    > @session[:constant_name] = constant_name
    >
    > end
    >
    > def abc_method
    >
    > @constant = MyClass.const_get(@session[:constant_name])
    > puts @constant
    >
    > end
    > end
    >
    > c = MyClass.new
    > c.xyz_method
    > c.abc_method
    >
    > This works. Since I don't know anything about rails and the live tree plugin,
    > I may have missed something related to them. You can try using
    > MyClass.constants in the abc_method to get a list of the constants defined
    > for MyClass; this could give you some hints about what's happening.
    >
    > Stefano
    >
    >
    >
     
    Tom V., May 6, 2007
    #5
  6. On 5/6/07, Tom V. <> wrote:
    > Hi Stefano,
    >
    > it's not working for me.
    > MyClass.const_get always returns a NameError.
    > Trying:
    >
    > MyClass.const_defined?(session[:constant_name])
    >
    > always returns 'false'
    > (except for the method where constant_name was defined...).
    >
    > My guess is that 'session' cannot store Constants created the way I do it.
    > However, storing other large and complex objects is not a problem.


    You guess is in the territory, but it's not really about session's
    capability. if xyz_method is a controller action for instance, and
    abc_method is a controller action, there's nothing guaranteeing per se
    that you're state is going to be persisted between user interactions
    with the web app. What you really need to store in session is the name
    of the constant, AND it's value. and then you need to const_set it at
    the beginning of every method where you make use of this live tree
    thing.
    > >

    >
    >
     
    Logan Capaldo, May 6, 2007
    #6
  7. Tom V.

    Tom V. Guest

    "Logan Capaldo" <> wrote:
    >
    > You guess is in the territory, but it's not really about session's
    > capability. if xyz_method is a controller action for instance, and
    > abc_method is a controller action, there's nothing guaranteeing per se
    > that you're state is going to be persisted between user interactions
    > with the web app. What you really need to store in session is the name
    > of the constant, AND it's value. and then you need to const_set it at
    > the beginning of every method where you make use of this live tree
    > thing.
    >


    Hi,
    Creating a new constant from session data still doesn't work.
    As you said I now store both constant_name and constant_value in session.

    However, when trying to test the new Constant (const_defined?),
    I get a NameError (see below).

    Also, when printing it, its value is printed, not its name:
    "{@new_constant}" --> "/path/to/nirvana".
    How do I access its name?

    Maybe you find an error in code.
    Or maybe you know of another way
    to create dynamically named variables..?


    class AbcController < ApplicationController

    before_filter :get_constants, :except => :define_constants

    def define_constants
    @user = "tom"
    constant_name = "#{@user.upcase}_PATH"
    logger.info("#{constant_name}")
    # output: TOM_PATH

    constant_value = self::class::const_set(constant_name, "/path/to/nirvana")
    logger.info("#{constant_value}")
    # output: /path/to/nirvana

    session[:constant_name] = constant_name
    session[:constant_value] = constant_value
    end

    def get_constants
    if session[:constant_name]
    @constant_name = session[:constant_name]
    logger.info("#{@constant_name}")
    # output: TOM_PATH

    if session[:constant_value]
    @constant_value = session[:constant_value]
    logger.info("#{@constant_value}")
    # output: /path/to/nirvana

    @new_constant = self::class::const_set(@constant_name, @constant_value)
    logger.info("#{@new_constant}")
    # output: /path/to/nirvana

    evaluate_constant = self::class::const_defined?(@new_constant)
    # output: NameError (wrong constant name /path/to/nirvana)

    end
    end
    end

    end

    Thanks for your input,
    Tom.
     
    Tom V., May 6, 2007
    #7
  8. Tom V.

    Tom V. Guest

    Hi Logan,

    thanks for the hint.
    However that did not get me too far.

    So now I use simple instance variables
    and the session storage utility.

    But I always get a strange error that let me to the idea
    of using constants in the first place...

    Although this is a rails project using a plugin,
    the error I get is from using std ruby libraries.
    so maybe you can enlighten me...
    Please have a quick look:

    Constructor for creating a new "live_tree":

    class MyController
    # ...
    live_tree :fstree, :find_item_proc =>
    Proc.new { |x| FileSystemItem.new(x, @user_path) }
    # ...
    end

    class FileSystemItem
    def initialize(path, root)
    @path = path
    log << "root = #{root} - class = #{root.class}\n"
    # output:
    # root = /user/path/ - class = String

    @root = File.expand_path(root)
    # ERROR:
    # TypeError (can't convert nil into String):
    # .//app/models/file_system_item.rb:17:in `expand_path'
    # .//app/models/file_system_item.rb:17:in `initialize'
    # .//app/controllers/my_controller.rb:452:in `new'
    end
    end

    "root" contains the user path and is of type String.
    However, when calling File.expand_path,
    I get the NameError.

    When using a constant or a global variable
    this error does not occur...

    Any ideas?

    Thanks for your time,
    Tom.


    On Mon, 7 May 2007 03:53:12 +0900
    "Logan Capaldo" <> wrote:
    > > @new_constant = self::class::const_set(@constant_name,
    > > @constant_value)
    > > logger.info("#{@new_constant}")
    > > # output: /path/to/nirvana
    > >
    > > evaluate_constant = self::class::const_defined?(@new_constant)

    >
    > should be self::class:const_defined?(@constant_name) of course.
    > @new_constant is gonna hold the value of the constant, not the name.
     
    Tom V., May 7, 2007
    #8
  9. Tom V.

    Tom V. Guest

    On Mon, 7 May 2007 20:26:10 +0900
    "Logan Capaldo" <> wrote:
    >
    > That seems really weird. Maybe ruby is not being as clear with reporting the
    > error as it could be. At this point I'd try using a debugger to get to the
    > bottom of it.
    >


    ok, thanks.
    do you happen to know a decent ruby debugger..?
    haven't found one so far.
    I am using linux.
    Tom.
     
    Tom V., May 7, 2007
    #9
  10. On 5/7/07, Tom V. <> wrote:
    > On Mon, 7 May 2007 20:26:10 +0900
    > "Logan Capaldo" <> wrote:
    > >
    > > That seems really weird. Maybe ruby is not being as clear with reporting the
    > > error as it could be. At this point I'd try using a debugger to get to the
    > > bottom of it.
    > >

    >
    > ok, thanks.
    > do you happen to know a decent ruby debugger..?
    > haven't found one so far.
    > I am using linux.


    My weapon of choice when I want to pull out the big guns is
    ruby-debug, it's available as a gem.

    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
     
    Rick DeNatale, May 7, 2007
    #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. Replies:
    9
    Views:
    1,013
  2. Pete Hodgson

    dynamically assigning class constants

    Pete Hodgson, Sep 6, 2008, in forum: Ruby
    Replies:
    4
    Views:
    95
    Pete Hodgson
    Sep 6, 2008
  3. Daniel Berger
    Replies:
    1
    Views:
    131
    Eric Hodel
    May 5, 2009
  4. Marli Ba
    Replies:
    3
    Views:
    95
    Marli Ba
    Oct 15, 2009
  5. Ronny
    Replies:
    6
    Views:
    141
Loading...

Share This Page