Daniel DeLorme wrote:
Furthermore this does not happen with builtin classes.
I’m not sure what you mean by that part. I get the same if I use String
instead of your class A:
a = String
a_meta = (class << a;self;end)
def a.foobar; end
p a.singleton_methods
p a_meta.instance_methods(false)
with 1.8.6p114 I get:
[“foobar”]
[“allocate”, “foobar”, “superclass”, “new”]
with 1.9.1-preview2 I get:
[:try_convert, :foobar]
[:try_convert, :foobar, :allocate, :new, :superclass]
But notice what happens if I try an instance of String (which is
comparable to what you were doing with an instance of class Object)
a = String.new
a_meta = (class << a;self;end)
def a.foobar; end
p a.singleton_methods(false)
p a_meta.instance_methods(false)
[“foobar”]
[“split”, “rstrip!”, “to_sym”, “swapcase”, “chop”, “foobar”, “empty?”,
“swapcase!”, “to_f”, “casecmp”, “rindex”, “intern”, “tr”, “to_s”,
“reverse!”, “strip!”, “match”, “hex”, “each”, “include?”, “slice”,
“next!”, “*”, “downcase!”, “downcase”, “sub”, “+”, “=~”, “upto”,
“concat”, “lstrip”, “each_byte”, “succ!”, “chop!”, “size”, “dump”,
“rjust”, “squeeze”, “delete!”, “eql?”, “next”, “reverse”, “sub!”,
“insert”, “chomp”, “[]”, “inspect”, “tr!”, “replace”, “[]=”, “scan”,
“tr_s”, “lstrip!”, “succ”, “<<”, “oct”, “gsub”, “capitalize!”, “to_i”,
“hash”, “capitalize”, “crypt”, “index”, “chomp!”, “rstrip”, “sum”,
“upcase!”, “center”, “upcase”, “count”, “squeeze!”, “unpack”, “<=>”,
“strip”, “==”, “length”, “gsub!”, “each_line”, “slice!”, “ljust”,
“to_str”, “%”, “delete”, “tr_s!”]
So you can see the instance methods of the object’s metaclass include
the instance methods of that object’s class. From one point of view this
seems reasonable to me; the metaclass is like a ‘private subclass’ to
the real class.
From another point of view, you might expect instance_methods(false) not
to return those methods. But I think that just explains why we have a
separate singleton_methods method - if you really want just the
singleton methods, not including the methods of the concrete class, call
that.