Reputation:
I am trying to access a module function that I have overriden in the class.
module Base
def Hello
puts "Hello"
end
end
class Top
include Base
def Hello
puts "hello from top"
end
def Hi
if p == 1
Hello
else
Base::Hello
end
end
end
But I get the following error -
Error: undefined method `Hello' for Base:Module
Is there any way I can access the module function without using self.Hello in function definition.
Upvotes: 1
Views: 1382
Reputation: 2114
If you are overwriting a instance method of a module within your class, you can call this method using super
.
module Base
def Hello
puts "Hello"
end
end
class Top
include Base
def Hello
if p == 1
puts "hello from top"
else
super
end
end
end
t = Top.new
t.Hello # => "Hello"
Upvotes: 0
Reputation: 949
You didn't understand meaning of include
!
When you include a module to a class methods from a module add to a object inheritance chain. In this way You can call that methods like own.
module A
def hello
p 'Hello from A'
end
end
class MyClass
include A
end
2.2.2 :010 > mm = MyClass.new
=> #<MyClass:0x00000000ecaa68>
2.2.2 :011 > mm.hello
"Hello from A"
You can use next in your case:
module B
def self.hello
p 'Hello from B'
end
end
class MyClass
def my_hello
B.hello #direct call from module B
end
end
And one more note: Don't use capitalized name for a method
Upvotes: 0
Reputation: 4970
One way you can do this is to make the module's method a module method rather than an instance method. If you precede the method definition with module_function
, then both a module and an instance method will be created. This will enable you to access the module method using the module's name (in this case, BaseModule.hello
). I've trimmed your question code to the essentials and illustrated how that would work:
#!/usr/bin/env ruby
module BaseModule
module_function
def hello
puts 'Hello from BaseModule'
end
end
class MyClass
include BaseModule
def hello
puts 'Hello from MyClass'
end
def module_hello
BaseModule.hello
end
end
MyClass.new.hello # Hello from MyClass
MyClass.new.module_hello # Hello from BaseModule
Upvotes: 1
Reputation: 121000
You demonstrated the complete misunderstanding of OOP concepts. And, BTW, the method names in Ruby are not to be started with capital letter.
One can not just call an arbitrary method somewhere in the class hierarchy. Whether this was possible, the whole OOP would make absolutely no sense.
One might call the super
method from within this method:
module Base
def hello
puts "Hello"
end
end
class Top
include Base
def initialize p
@p = p
end
def hello
if @p == 1
puts "hello from top"
else
super
end
end
def hi
hello
end
end
Top.new(1).hi
#⇒ hello from top
Top.new(2).hi
#⇒ Hello
or, one might declare the module function, a.k.a. static function and call it from everywhere:
module Base
def self.hello
puts "Hello"
end
end
class Top
# NOT NEEDED include Base
def hello
puts "hello from top"
end
def hi
if p == 1
hello
else
Base.hello
end
end
end
Upvotes: 3