在Ruby方法中不调用gets

时间:2013-04-03 17:12:53

标签: ruby

在Ruby中,我想向用户显示实例变量的值,然后使用gets.chomp询问值应该是什么。因为我将为几个变量执行此操作,所以我想使用方法检查值。我的困难在于,当我在方法中调用gets时,程序运行时不需要用户输入。

以下是代码的相关部分:

class TagPodcast

  # ... Code to pull ID3v2 tags from MP3 file

  def inspect_tags
    puts "Title: " + @title
    set_tag(self.title)
  end

  def set_tag(tag)
    new_value = gets.chomp
    tag = new_value unless new_value == ""
  end

end

TagPodcast.new("myfile.mp3").inspect_tags

当我运行程序时,它会打印Title: My Title Here,但随后退出而不要求输入。致电gets我需要做什么?

2 个答案:

答案 0 :(得分:2)

这个(轻微修改过的)程序要求我按预期输入(只添加了访问器和构造函数):

class TagPodcast
  attr_accessor :title

  def initialize(filename)
    @filename = filename
  end

  def inspect_tags
    puts "Title: " + @title
    set_tag(self.title)
  end

  def set_tag(tag)
    new_value = gets.chomp
    tag = new_value unless new_value == ""
  end
end

tp = TagPodcast.new("myfile.mp3")
tp.title = 'Dummy Title'

tp.inspect_tags

但是,您的代码有一个不同的问题。变量按值传递到方法中,而不是通过引用传递给方法,因此此代码将不会按预期运行:

class Foo
  attr_accessor :variable

  def set_var(var)
    var = 'new value'
  end

  def bar
    self.variable = 'old value'
    set_var(self.variable)

    puts "@variable is now #{self.variable}"
  end
end

Foo.new.bar

这将打印@variable is now old value。我可以想到两种解决方法。在方法之外设置实例变量,如下所示:

class Foo
  attr_accessor :variable

  def do_stuff
    'new value'
  end

  def bar
    self.variable = 'old value'
    self.variable = do_stuff

    puts "@variable is now #{self.variable}"
  end
end

Foo.new.bar

或使用Ruby强大的元编程功能,并利用instance_variable_set通过将其名称作为符号传递来动态设置实例变量:

class Foo
  attr_accessor :variable

  def set_var(var)
    instance_variable_set var, 'new value'
  end

  def bar
    self.variable = 'old value'
    set_var(:@variable)

    puts "@variable is now #{self.variable}"
  end
end

Foo.new.bar

至于您的原始问题,我们需要了解有关执行上下文的更多信息。可能STDIN不是你在执行时期望的那样。

答案 1 :(得分:0)

确保您从标准输入获得输入:

STDIN.gets.chomp

$stdin.gets.chomp