Ancestor paths

P

Perry Smith

ActiveRecord does this "trick". For a normal object, this dump
routine:

def dump(name, obj)
puts "#{name}'s ancestors: #{obj.class.ancestors.inspect}"
puts "#{name}'s funky ancestors: #{(class << obj; self;
end).ancestors.inspect}"
end

produces the same list for ancestors and funky ancestors. For an
ActiveRecord Association, you get something like this:

temp's ancestors: [ Cached::Queue <snip...>
ActiveRecord::Locking::pessimistic, ActiveRecord::Locking::Optimistic,
ActiveRecord::Validations, Object, Socket::Constants,
InstanceExecMethods, Base64::Deprecated, Base64, Kernel]

temp's funky ancestors:
[ActiveRecord::Associations::BelongsToAssociation,
ActiveRecord::Associations::AssociationProxy, Object, Socket::Constants,
InstanceExecMethods, Base64::Deprecated, Base64, Kernel]

Can someone tell me how this is done or point me to the code in active
record?

Thank you very much,
Perry
 
P

Perry Smith

Perry said:
ActiveRecord does this "trick". For a normal object, this dump
routine:

FINALLY...

This simple program:

#!/usr/bin/env ruby

def dump(name, obj)
puts "#{name}'s class: #{obj.class}"
puts "#{name}'s ancestors: #{obj.class.ancestors.inspect}"
puts "#{name}'s meta ancestors: #{(class << obj; self;
end).ancestors.inspect}"
end

class Goofy
alias_method :proxy_respond_to?, :respond_to?
instance_methods.each { |m| undef_method m unless m =~
/(^__|^nil\?$|^send$|proxy_)/ }

def initialize(o)
@target = o
end

def respond_to?(symbol, include_priv = false)
proxy_respond_to?(symbol, include_priv) ||
@target.respond_to?(symbol, include_priv)
end

private

def method_missing(method, *args, &block)
@target.send(method, *args, &block)
end
end

g = Goofy.new("hi")

dump("g", g)

Produces this output:

g's class: String
g's ancestors: [String, Enumerable, Comparable, Object, Kernel]
g's meta ancestors: [Goofy, Object, Kernel]

Geeze that took me a long time to figure out.
 
P

Perry Smith

Perry said:
g's class: String
g's ancestors: [String, Enumerable, Comparable, Object, Kernel]
g's meta ancestors: [Goofy, Object, Kernel]

And, in my case, I added a method to String and to Object (the one in
String was more specific). But g.meth was going to the one in Object
instead of String. The reason is because it is not a missing method so
it doesn't get proxied.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,216
Latest member
topweb3twitterchannels

Latest Threads

Top