Bug #12535
closedare there 2 sleep methods defined?
Description
I'm updating this gem which "patches" the sleep method to use prepend, as I wanted to drop support to ruby < 2.0 . (previous implementation was using alias method chain like solution)
So I came across this funny behaviour:
module AlternativeSleep
def sleep(*)
puts "going to sleep now..."
super
end
end
class << self
prepend AlternativeSleep
end
class << Kernel
prepend AlternativeSleep
end
puts "these are the locations..."
puts Kernel.method(:sleep)
puts method(:sleep)
puts "now to work. if you see the going to sleep message only once, there's your bug"
Kernel.sleep 1
sleep 1
In order to make sleep work in both cases, I have to do those 2 prepends. Try to comment one of them, and you'll see that one of them will always work.
I'm led to believe that sleep method has two implementations, although that doesn't seem to make sense. Could you provide with some insight?
When I was using the alias-method-chain example, I was including in the main object, as main#sleep
somehow seemed to land in Kernel.sleep
(?) .
Updated by nobu (Nobuyoshi Nakada) over 7 years ago
- Description updated (diff)
- Status changed from Open to Rejected
No.
You are prepending the method on 2 different objects, main
and Kernel
.
Updated by chucke (Tiago Cardoso) over 7 years ago
Yes I am. My point being, I can't overwrite the sleep method only in one place, as it is apparently defined in two different objects. Why not just one?
The main.timeout method (which has been already deprecated) at least redirected to Timeout.timeout, which meant I only had to patch that one.
Updated by chucke (Tiago Cardoso) over 7 years ago
- Assignee set to nobu (Nobuyoshi Nakada)
@nobu (Nobuyoshi Nakada), can you check my last comment? I think this is a valid concern, as in "the same method defined in two objects".
Updated by nobu (Nobuyoshi Nakada) over 7 years ago
- Assignee deleted (
nobu (Nobuyoshi Nakada))
If you want to overwrite the method globally, prepend the module to Kernel
instead of the singleton class of it.
Updated by chucke (Tiago Cardoso) over 7 years ago
I've just tried that, it's not delivering the expected result. Try this out:
module AlternativeSleep
def sleep(*)
puts "going to sleep now..."
super
end
end
Kernel.prepend AlternativeSleep
# none of these work
Kernel.sleep 1
sleep 1
I guess it's because Kernel is a module already.