Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

question about parameter passing in Ruby

Comparing the following two code snippets:

class Logger 
  def self.add_logging(id_string)
    define_method(:log) do |msg| 
      now = Time.now.strftime("%H:%M:%S")
      STDERR.puts "#{now}-#{id_string}: #{self} (#{msg})"
    end 
  end
end 

class Song < Logger
  add_logging "Tune" 
end

song = Song.new 
song.log("rock on")

class Logger
  def self.add_logging(id_string)
    def log(msg)
      now = Time.now.strftime("%m")
      puts "#{now}-#{id_string}: #{self}(#{msg})"
    end
  end
end

class Song < Logger
  add_logging "Tune"
end

s = Song.new

s.log("can't smile with you")
#=> NameError: undefined local variable or method `id_string' for #<Song:0x000001018aad70>

I can't figure out why the second case gets the NameError error, and why the id_string can't be passed to it.

like image 340
mko Avatar asked Jan 19 '26 20:01

mko


1 Answers

A def creates a new scope; a block does not. A new scope cuts off the visibility of the surrounding variables. ruby has two other 'new scope creators': class and module.

x = 10

3.times do |i|
  puts i * x
end

def do_stuff
  puts x * 10
end

do_stuff  

--output:--
0
10
20
`do_stuff': undefined local variable or method `x' 
like image 95
7stud Avatar answered Jan 21 '26 12:01

7stud



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!