6

I'm new to this but I have the following code:

when /^read (.+)$/
   puts "Reading #{$1}:"
   puts $1.description.downcase

I would like to use $1 as a variable that I can call methods on, currently the interpreter returns a "NoMethodError: undefined method 'description' for "Door":String".

Edit:

For example:

door = Item.new( :name => "Door", :description => "a locked door" )
key  = Item.new( :name => "Key",  :description => "a key"         )
Phrogz
  • 296,393
  • 112
  • 651
  • 745
Jake Burton
  • 63
  • 1
  • 3
  • Possible duplicate of _[Using a string as a variable at run time in Ruby on Rails](http://stackoverflow.com/questions/881239/using-a-string-as-a-variable-at-run-time-in-ruby-on-rails)_ or _[Using a String as a Function Name](http://stackoverflow.com/questions/877882/using-a-string-as-function-name/878174)_. – Phrogz May 07 '11 at 12:23

2 Answers2

10

You need to provide more details of your code setup to get a good answer (or for me to figure out which question this is a duplicate of :). What kind of variables are referenced by $1? Here are some guesses:

  1. If this is actually a method on the same instance, you can invoke this method by:

    # Same as "self.foo" if $1 is "foo"
    self.send($1).description.downcase 
    
  2. If these are instance variables, then:

    # Same as "@foo.description.downcase"
    instance_variable_get(:"@#{$1}").description.downcase
    
  3. If these are local variables, you can't do it directly, and you should change your code to use a Hash:

    objs = {
      'foo' => ...,
      'key' => Item.new( :name => "Key", :description => "a key" )
    }
    objs['jim'] = ...
    case some_str
      when /^read (.+)$/
        puts "Reading #{$1}:"
        puts objs[$1].description.downcase
    end
    
Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • My Variables look like this: key = Item.new( :name => "Key", :description => "a key" ) Key is referenced by $1 – Jake Burton May 07 '11 at 12:48
  • @Jake Then you have a bad (but common) design and you should instead be storing them in a Hash per #3 above. – Phrogz May 07 '11 at 13:12
  • What's the alternative that you propose to this bad design? If it's too long to explain, a quick keyword I should Google would be helpful. – Seanny123 Nov 29 '13 at 02:55
  • @Seanny123 It's spelled out above, and in my comments: use a Hash to store your data instead of local variables. – Phrogz Nov 29 '13 at 04:32
0

I guess you matched a string like "read Door" with /^read (.+)$/. So $1 = "Door" and it raised the above error. If you want to downcase that string, just use:

$1.downcase

Hoang Tran
  • 309
  • 3
  • 6
  • Thats right, Though I want to print the description stored with it. e.g. puts $1.description.downcase. The variable that stores this is door = Item.new( :name => "Door", :description => "a locked door" ) – Jake Burton May 07 '11 at 12:52