Search code examples
rubyrubygemsbundler

Undefined method error for main:Object when using gem


Testing out making a gem, figured logic gates would be more or less effortless(if useless) to actually implement so I used them. I have this code in my lib/logic.rb file:

require "logic/version"

module Logic
  def or_gate(a, b)
    a || b
  end

  def and_gate(a, b)
    a && b
  end

  def nand_gate(a, b)
    !(a && b)
  end

  def nor_gate(a, b)
    !(a || b)
  end

  def not_gate(a)
    !a
  end

  def xor_gate(a, b)
    !(a == b)
  end

  def xnor_gate(a, b)
    a == b
  end
end

I can build and install the gem without issue, but when testing with irb calling the or_gate method for example just returns a "NoMethodError: undefined method 'or_gate' for main:Object'. Doing something like

Logic.or_gate

or

Logic::Gate.or_gate 

(putting methods in a Gate class) both have the same problem. What am I doing wrong?


Solution

  • You have defined instance methods, not module methods. Change:

    def or_gate(a, b)
    

    to:

    def self.or_gate(a, b)
    

    and it'll work the way you expect:

    Logic.or_gate(1,2)
     => 1
    

    Repeat this change for all your method definitions.

    Alternatively, you can use extend self to accomplish the same goal without having to add self. to each method definition:

    module Logic
      extend self
    
      def or_gate(a, b)
        a || b
      end
    end
    

    This adds/copies all the instance methods as module methods.

    There is more discussion of this here, and this answer goes into some more detail on how methods are defined in modules.