Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > little tool for learning the ruby lookup path

Reply
Thread Tools

little tool for learning the ruby lookup path

 
 
timr
Guest
Posts: n/a
 
      01-03-2011
I have been looking at the process ruby utilizes for method lookup,
and wrote the code below. It has proven very enlightening to me. I am
sharing. It allows obj#method_table to be called where one normally
uses obj#methods. It inserts markers (conspicuous method names) into
the method array that delimit the source for the listed methods up to
that point so that it is clear how the method array is composed. See
the test case at the bottom for clarification.

The most thrilling thing I have done this entire year is to monkey-
patch methods and see them hop to the appropriate section of the
method_table and disappear from the previous position.

I'd be interested to hear any feedback interested rubyists have about
the approach or if anyone has suggestions to refactor the code.
Thanks,
Tim


module Kernel
def method_table
#for completness sake, include the self in inh_chain, that way we
can see the singleton_methods if any exist
inh_chain = self.class.ancestors.unshift(self)

inh_chain.each do |anc|
meth_name = anc.to_s.center(20,'_')
#define bookmark method to mark the position of that portion of
the lookup path
if anc.respond_to? :class_eval
begin
anc.class_eval("def #{meth_name}; end" )
rescue
end
end
if anc.respond_to?(:define_singleton_method)
begin

anc.define_singleton_method("singleton_to_left".to _s.center(25,'_').to_sym)
{}
#uncommnet the following line to see how subsequent
singleton methods stack on

#anc.define_singleton_method("Bsingleton".to_s.cen ter(20,'').to_sym){}

meth_name = "extension_to_right".to_s.center(25,'_').to_sy m
anc.extend(Module.new{eval("def #{meth_name};end")})

#uncommnet the following lines to see how subsequent
extended methods stack on
#meth_name = "extension".to_s.center(20,'→').to_sym
#anc.extend(Module.new{eval "def B#{meth_name};end;def
C#{meth_name};end"})
rescue
end
end
end
self.methods
end
end


#######TEST CASE###########
module First
def added_in_first
end
end
module Second
def added_in_second
end
end
class NewObject
include First
end
no = NewObject.new
no.extend(Second)
def no.singleton_method
end
p no.method_table

=>[:singleton_method, :____singleton_to_left____, :___extension_to_right____, :added_in_second, :_____NewObject______, :added_in_first, :_______First________, :_______Object_______, :nil?, :===, :=~, :!
~, :eql?, :class, :clone, :dup, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_methods, rotected_methods, rivate_methods, ublic_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?, :instance_of?, :kind_of?, :is_a?, :tap, :send, ublic_send, :respond_to?, :extend, :display, :method, ublic_method, :define_singleton_method, :hash, :__id__, bject_id, :to_enum, :enum_for, :gem, :method_table,:_______Kernel_______, :==, :equal?, :!, :!
=, :instance_eval, :instance_exec, :__send__, :____BasicObject_____]
 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      01-03-2011
On Mon, Jan 3, 2011 at 10:05 AM, timr <> wrote:
> I have been looking at the process ruby utilizes for method lookup,
> and wrote the code below. It has proven very enlightening to me. I am
> sharing. It allows obj#method_table to be called where one normally
> uses obj#methods. It inserts markers (conspicuous method names) into
> the method array that delimit the source for the listed methods up to
> that point so that it is clear how the method array is composed. See
> the test case at the bottom for clarification.
>
> The most thrilling thing I have done this entire year is to monkey-
> patch methods and see them hop to the appropriate section of the
> method_table and disappear from the previous position.


IMHO monkey patching should not be general practice and stay limited
to particular cases because of the dangers it creates.

> I'd be interested to hear any feedback interested rubyists have about
> the approach or if anyone has suggestions to refactor the code.


What I don't like about your approach is that you _modify_ what you
investigate. Analyzing where a method comes from should not change
any of the classes involved.

Then, I'd define this method as an instance method of Object because
you want to investigate methods of a particular instance (even if it
is a class or module).

Finally, for classifying things a Hash seems a much better choice than an Array.

I'd rather do something like this:

require 'pp'

class Object
def method_table
Hash.new {|h,k| h[k] = []}.tap do |tbl|
methods.each do |m|
tbl[method(m).owner] << m
end
end
end
end

s = "foo"
def s.bar;123;end

pp s.method_table

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

 
Reply With Quote
 
 
 
 
timr
Guest
Posts: n/a
 
      01-03-2011
Hi Robert,
Thanks for your massive improvements, and insights. I didn't like
modifying the object during the investigation, but didn't know about
obj#method(m).owner. I can't believe I hadn't seen that before. Your
version is beautiful.
Thanks for helping,
Tim



On Jan 3, 1:35*am, Robert Klemme <shortcut...@googlemail.com> wrote:
> On Mon, Jan 3, 2011 at 10:05 AM, timr <timra...@gmail.com> wrote:
> > I have been looking at the process ruby utilizes for method lookup,
> > and wrote the code below. It has proven very enlightening to me. I am
> > sharing. It allows obj#method_table to be called where one normally
> > uses obj#methods. It inserts markers (conspicuous method names) into
> > the method array that delimit the source for the listed methods up to
> > that point so that it is clear how the method array is composed. See
> > the test case at the bottom for clarification.

>
> > The most thrilling thing I have done this entire year is to monkey-
> > patch methods and see them hop to the appropriate section of the
> > method_table and disappear from the previous position.

>
> IMHO monkey patching should not be general practice and stay limited
> to particular cases because of the dangers it creates.
>
> > I'd be interested to hear any feedback interested rubyists have about
> > the approach or if anyone has suggestions to refactor the code.

>
> What I don't like about your approach is that you _modify_ what you
> investigate. *Analyzing where a method comes from should not change
> any of the classes involved.
>
> Then, I'd define this method as an instance method of Object because
> you want to investigate methods of a particular instance (even if it
> is a class or module).
>
> Finally, for classifying things a Hash seems a much better choice than anArray.
>
> I'd rather do something like this:
>
> require 'pp'
>
> class Object
> * def method_table
> * * Hash.new {|h,k| h[k] = []}.tap do |tbl|
> * * * methods.each do |m|
> * * * * tbl[method(m).owner] << m
> * * * end
> * * end
> * end
> end
>
> s = "foo"
> def s.bar;123;end
>
> pp s.method_table
>
> Kind regards
>
> robert
>
> --
> remember.guy do |as, often| as.you_can - without endhttp://blog.rubybestpractices.com/


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Long Path Tool - Fix Path Too Long Forever Martin Krag Wireless Networking 1 12-15-2012 02:53 PM
Long Path Tool - Fix Path Too Long Forever Martin Krag Windows 64bit 0 03-31-2011 08:24 AM
1 little 2 little 3 little Kennedys dale Digital Photography 0 03-23-2008 01:03 PM
comman lookup tool Tuhin Cisco 1 09-10-2005 11:46 AM
A new japanese dictionary and learning tool in Ruby Mathieu Blondel Ruby 0 06-20-2005 05:40 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57