Search code examples
rubylogginginstance-variablesself

How do I log a message when I run a method in a class?


I wrote the following code. When I run Hello.run I want to log a message, but this does not work.

Why does not this work?

class Hello
  def initialize
    @logger = Logger.new STDOUT
  end

  def self.run
    self.new
    @logger.warn 'Hello'
  end
end

Hello.run

This is the error message I get when running Hello.run

NoMethodError: private method `warn' called for nil:NilClass

Solution

  • The @logger variable you set in the constructor is an instance variable, and self.run is a class method.

    Instance variables are not available in class methods, so when you're running Hello.run, you won't be able to access the Hello class' internal instance variable.

    If you want the logger to be class wide, you could define it as a class variable, like so:

    class Hello
      def initialize
        @@logger ||= Logger.new(STDOUT)
      end
    
      def self.run
        self.new # I don't get why you just create a new instance and throw it away
        @@logger.warn("Hello")
      end
    end
    

    I have a longer answer on different variable scopes here, if you are interested.