On Jun 11, 2006, at 7:17 AM, Daniel Berger wrote:

> Is there a way to get a list of instance method aliases somehow?
>
> # Hypothetical syntax
> Array.instance_method_aliases # ['size', 'map', ...]
>
> If not, I think it would be a nice little bit of extra inspection I  
> could use in certain situations, like when I'm in irb and feeling  
> too lazy to look at the documentation. ;)
>
> Actually, this idea struck me when I tried to figure out just the  
> "core" methods for a given class and wanted to exclude the  
> aliases.  At the time, I had to view the source code directly and  
> count them.  This proved more difficult than I thought, because  
> sometimes methods would redefine functions with different names  
> rather than use rb_define_alias() in the source code.
>
> To give you an example of what I mean, in array.c the Array#map  
> function is not declared using rb_define_alias(), but is simply  
> mapped (no pun intended) to a different function:
>
> rb_define_method(rb_cArray, "collect", rb_ary_collect, 0);
> rb_define_method(rb_cArray, "map", rb_ary_collect, 0);

WARNING: this gets gross:

It is a little less relevant with the core classes (seeing how they  
don't change very much), but easier to figure out what is aliased.  
You can use ParseTree to get the sexps for the class Array, and then  
it becomes pretty "obvious":

ruby -I../RubyInline/dev:lib -rparse_tree -e 'class Array;  
alias :blah :map; end; p ParseTree.new.parse_tree(Array)'

[[:class, :Array, :Object, ...
   [:defn, :blah, [:fbody, [:cfunc, 504080, 0]]], ...
   [:defn, :collect, [:cfunc, 504080, 0]],
   [:defn, :collect!, [:cfunc, 504206, 0]], ...
   [:defn, :map, [:cfunc, 504080, 0]],
   [:defn, :map!, [:cfunc, 504206, 0]], ...
]]

So, with c-implemented functions, your :defn is pretty much just a  
pointer to the C-function. You can compare the addresses and see  
what's been aliased. Likewise, with a real alias to a :cfunc you can  
dig a bit deeper and see that it points to it properly.

In the case of aliases on ruby methods, it gets harder:

% ruby -I../RubyInline/dev:lib -rparse_tree -e 'class X; def y; end;  
alias :x :y; end; p ParseTree.new.parse_tree(X)'

[[:class, :X, :Object,
   [:defn, :x, [:fbody, [:scope, [:block, [:args], [:nil]]]]],
   [:defn, :y,          [:scope, [:block, [:args], [:nil]]]]]]

So, while you can conclude that :fbody is a marker for an alias to  
SOMETHING, you can't tell what because it is already expanded. You  
should be able to either compare sexps or use some C to dig in and  
see that the implementations (nd_body pointer) have the same address.  
The code in question is:

>     st_insert(RCLASS(klass)->m_tbl, name,
>       (st_data_t)NEW_METHOD(NEW_FBODY(body, def, origin), orig- 
> >nd_noex));

so the addresses should be the same. (yes, either option is rather  
icky).