Reputation: 6455
In Ruby, I want to display the value of an instance variable to the user, then ask what the value should be using gets.chomp
. Because I'll be doing this for several variables, I want to check the value with a method. My difficulty is that when I call gets
in a method, the program runs without asking for user input.
Here is the relevant part of code:
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
When I run the program, it prints Title: My Title Here
but then exits without asking for input. What do I need to do to call gets
?
Upvotes: 0
Views: 108
Reputation: 54724
This (sligtly modified) program asks me for input as expected (just added accessor and constructor):
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
Your code has a different problem, though. Variables are passed into methods by value, not by reference, so this code will not behave as expected:
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
this will print @variable is now old value
. I can think of two ways around this. Either set the instance variable outside the method like so:
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
or use Ruby's powerful metaprogramming features and leverage instance_variable_set
to dynamically set an instance variable by passing its name as a symbol:
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
As for your original question, we need to know more about the execution context. Probably STDIN is not what you expect it to be at execution time.
Upvotes: 2
Reputation: 70235
Ensure that you are getting input from standard input with:
STDIN.gets.chomp
or
$stdin.gets.chomp
Upvotes: 0