0

Here's the code:

module A
  class C1
    def self.grovel(x)
      return A::helper(x) + 3
    end
  end

  class C2
    def self.grovel(x)
      return A::helper(x) + 12
    end
  end
  private
  def helper(y)
    y + 7
  end
  module_function :helper
end

f = A::C1.grovel(7)
puts f
puts A::C2.grovel(25)

I'm working with legacy code, trying to avoid changing too much. I'm not sure I would have made two separate classes with the same method, as each class only contains one method, with common code. I want to extract the common code into a method that only the methods in A can see, but still have to invoke it with its fully qualified name ("A::helper").

Is there a better way of doing this? Ideally, I'd like to wrap the common code in a method (let's still call it "helper") that can be invoked from within the class grovel methods without any qualification, but isn't easily available to code outside module A.

Thanks.

Малъ Скрылевъ
  • 16,187
  • 5
  • 56
  • 69
Eric
  • 2,115
  • 2
  • 20
  • 29

2 Answers2

1

How about creating another module?

module A
  module Helper
    def helper(y)
      y + 7
    end
  end  

  class C1
    class << self
      include A::Helper    

      def grovel(x)
        return helper(x) + 3
      end
    end
  end

  class C2
    class << self
      include A::Helper    

      def grovel(x)
        return helper(x) + 12
      end
    end
  end


end

puts A::C1.grovel(7)
puts A::C2.grovel(25)

You create a submodule of A, and include it in your classes as a Mixin. That way only these classes can access the method.

You can see it working in http://rubyfiddle.com/riddles/31313

Alex Siri
  • 2,856
  • 1
  • 19
  • 24
  • Yeah, this disturbs the existing code the least. I was wondering if there was a metaprog way of finding the current module's methods and calling one, couldn't find it. – Eric Jan 17 '14 at 17:40
0

Minixs are useful, when the proper inheritance can't be applied, for example, then a class must be inherit properties of the two other classes, therefore you can just use the inheritance mechanics here:

module A
  class C
    def self.helper(y)
      y + 7
    end
  end

  class C1 < C
    def self.grovel(x)
      return self.helper(x) + 3
    end
  end

  class C2 < C
    def self.grovel(x)
      return self.helper(x) + 12
    end
  end
end

puts A::C1.grovel(7)
puts A::C2.grovel(25)
Малъ Скрылевъ
  • 16,187
  • 5
  • 56
  • 69