Reputation: 1038
So I have three different ways I can have class level methods on a module:
I usually do it this way if I have 3 or fewer:
module Foo
def self.speak
"Foo"
end
end
If I have more, I've traditionally done it this way:
module Bar
class << self
def speak
"Bar"
end
end
end
But recently, I came across this nifty way and have started using this more often:
module FooBar
extend self
def speak
"FooBar"
end
end
They all work:
Foo.speak => "Foo"
Bar.speak => "Bar"
FooBar.speak => "FooBar"
So, is there any material differences or gotchas to be aware of, esp. with the last form? The only real gotcha I can think of is that once you "extend self" all method defs following are class-level.
I've tried to think of some edge cases where one form works, but the other doesn't. Are there any?
Upvotes: 2
Views: 46
Reputation: 110675
The third form, unlike the first two, creates both an instance method :speak
and a module method :speak
:
module Foo
def self.speak
"Foo"
end
end
Foo.methods.include?(:speak) #=> true
Foo.instance_methods.include?(:speak) #=> false
class A
include FooBar
end
A.instance_methods.include?(:speak) #=> false
module Bar
class << self
def speak
"Bar"
end
end
end
Bar.methods.include?(:speak) #=> true
Bar.instance_methods.include?(:speak) #=> false
class A
include Bar
end
A.instance_methods.include?(:speak) #=> false
module FooBar
extend self
def speak
"FooBar"
end
end
FooBar.methods.include?(:speak) #=> true
FooBar.instance_methods.include?(:speak) #=> true
class A
include FooBar
end
A.instance_methods.include?(:speak) #=> true
Upvotes: 3