Project

General

Profile

Bug #12535

are there 2 sleep methods defined?

Added by chucke (Tiago Cardoso) over 2 years ago. Updated over 2 years ago.

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:76200]

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 (?) .

History

Updated by nobu (Nobuyoshi Nakada) over 2 years ago

  • Status changed from Open to Rejected
  • Description updated (diff)

No.
You are prepending the method on 2 different objects, main and Kernel.

#2

Updated by chucke (Tiago Cardoso) over 2 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 2 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 2 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 2 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.

Also available in: Atom PDF