【问题标题】:Use a string to access a local variable by name使用字符串按名称访问局部变量
【发布时间】:2026-01-31 03:50:01
【问题描述】:

我是新手,但我有以下代码:

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

我想使用 $1 作为我可以调用方法的变量,目前解释器返回一个"NoMethodError: undefined method 'description' for "Door":String"

编辑

例如:

door = Item.new( :name => "Door", :description => "a locked door" )
key  = Item.new( :name => "Key",  :description => "a key"         )

【问题讨论】:

标签: ruby


【解决方案1】:

您需要提供代码设置的更多详细信息才能获得好的答案(或者让我弄清楚这是哪个问题的重复:)。 $1 引用了哪些变量?以下是一些猜测:

  1. 如果这实际上是同一实例上的方法,您可以通过以下方式调用此方法:

    # Same as "self.foo" if $1 is "foo"
    self.send($1).description.downcase 
    
  2. 如果这些是实例变量,那么:

    # Same as "@foo.description.downcase"
    instance_variable_get(:"@#{$1}").description.downcase
    
  3. 如果这些是局部变量,你不能直接做,你应该改变你的代码使用哈希:

    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
    

【讨论】:

  • 我的变量如下所示: key = Item.new( :name => "Key", :description => "a key" ) Key 被 $1 引用
  • @Jake 那么你的设计很糟糕(但很常见),你应该将它们存储在上面 #3 的哈希中。
  • 对于这种糟糕的设计,您提出的替代方案是什么?如果解释的时间太长,我应该用 Google 的快速关键字会有所帮助。
  • @Seanny123 上面已经说明了,在我的 cmets 中:使用哈希而不是局部变量来存储数据。
【解决方案2】:

我猜你用 /^read (.+)$/ 匹配了一个像“read Door”这样的字符串。所以 $1 = "Door" 它引发了上述错误。如果你想 downcase 该字符串,只需使用:

$1.downcase

【讨论】:

  • 没错,虽然我想打印与它一起存储的描述。例如放 $1.description.downcase。存储这个的变量是 door = Item.new( :name => "Door", :description => "a lock door" )