Fun with singletons' singleton classes

Abusing the language:

batsman@tux-chan:/tmp$ expand -t 2 g.rb
class A
def self.method_added id
puts “Adding method #{id} to #{self}”
end
end

class A
def a
end
end

class A
p self.id
class << self
p self.id
def self.method_added id
p self.id
puts “Adding singleton method #{id} to #{self}”
end
end
end

class A
def self.a
end
end
batsman@tux-chan:/tmp$ ruby g.rb
Adding method a to A
538076252
538072582

I expected
Adding method a to A
538076252
538072582
XXXXXXXXX
Adding singleton method a to Class

Why is method_added not honored for singletons? Note it is perfectly
legal to define singletons’ singleton methods:

class A
class << self
def self.foo
puts “foo”
end
end
end
=> nil
class << A; foo; end
foo
=> nil

POLS would mean for me that singletons’ singletons should behave as “normal”
singletons or be completely unavailable.

···


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

Anyone want the new supermount? :slight_smile:
whats new aboutit
klogd: It cleans whiter than white. :slight_smile:
– Seen on #Linux

class A

      def self.singleton_method_added id
         puts "Adding singleton method #{id} to #{self}"
      end

  def self.method_added id
    puts "Adding method #{id} to #{self}"
  end

Guy Decoux

How do I do within singleton_method_added to remove a singleton method
if it matches some :name?

I tried

class << self
def singleton_method_added i
remove_method i if i == :method_added
end
end

and (more sensible)

def singleton_method_added i
(class << self; self; end).instance_eval <<-EOF
remove_method :#{i.to_s} if :#{i.to_s} == :method_added
EOF
end

I want to render impossible to redefine SomeClass.method_added without
freezing the singleton of SomeClass.

···

On Tue, Feb 04, 2003 at 01:05:50AM +0900, ts wrote:

class A

  def self.singleton_method_added id
     puts "Adding singleton method #{id} to #{self}"
  end

def self.method_added id
puts “Adding method #{id} to #{self}”
end


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

The only other people who might benefit from Linux8086 would be owners
of PDP/11’s and other roomsized computers from the same era.
– Alan Cox

How do I do within singleton_method_added to remove a singleton method
if it matches some :name?

pigeon% cat b.rb
#!/usr/bin/ruby
class A
  def self.singleton_method_added(id)
     puts "Adding singleton method #{id} to #{self}"
     if id != :singleton_method_added
        class << self; self; end.send(:remove_method, id)
     end
  end
end

class A
  def self.a
     p "A::a"
  end
end

A.a
pigeon%

pigeon% b.rb
Adding singleton method singleton_method_added to A
Adding singleton method a to A
./b.rb:17: undefined method `a' for A:Class (NameError)
pigeon%

Guy Decoux