Using strings to drill down into objects

Folks,
I’m writing a reporting application where I’m passing in an array
of
method calls to populate a table

e.g.

# lambda function to drill down object hierarchy
drill_down = lambda do |obj, method_name|
                      o ||= obj
                      method_name.split('.').each {|m| o = o.send(m) 

if
o.respond_to?(m)}
o
end

methods = [‘lookup1.code’, ‘lookup1.name’]

report_value = drill_down.call(my_object_with_lookups, methods)

I’m sure there is a better “Ruby” way of doing this. Can someone offer
some advice?

Ross D.
Developer
Data Management & Reporting
Link Administration Services

Tel Direct: (03) 9633 8165
Tel Office: (03) 9633 8000


This communication may contain CONFIDENTIAL information and may also be
the subject of LEGAL PROFESSIONAL PRIVILEGE and/or under copyright. If
you are not an intended recipient, you MUST NOT keep, forward, copy,
use, save or rely on this communication and any such action is
unauthorised and prohibited. If you have received this communication in
error, please reply to this e-mail to notify the sender of its incorrect
delivery, and then delete both it and your reply. Thank you


Ross X Dawson wrote:

report_value = drill_down.call(my_object_with_lookups, methods)
I’m not sure what your intent is, but I guess this code won’t work.

First, unless you define it before creating the lambda, “o” won’t exist
in its binding, so you can’t call o ||= obj. Second, you pass an array
of method names to your lambda as a second parameter, on which #split
isn’t defined.

You could state instead:

method_name.each{|name| name.split{|part| … } }

but then, “part” would take the value “lookup1”, “code”, “lookup1”
again, and “name” in that order. I highly doubt you want this.

However, AFAIK you’re right that o.send(m, *args) is the way to call an
arbitrary named method on an object.

mortee

mortee wrote:

Ross X Dawson wrote:

# lambda function to drill down object hierarchy
drill_down = lambda do |obj, method_name|
                      o ||= obj
                      method_name.split('.').each {|m| o = o.send(m) if

o.respond_to?(m)}
o
end

method_name.each{|name| name.split{|part| … } }

Sorry, that should read

method_name.each{|name| name.split(’.’).each{|part| … } }

On Oct 11, 8:32 am, mortee [email protected] wrote:

report_value = drill_down.call(my_object_with_lookups, methods)

I’m not sure what your intent is, but I guess this code won’t work.

First, unless you define it before creating the lambda, “o” won’t exist
in its binding, so you can’t call o ||= obj.

Are you sure about that?

[email protected]:~$ irb
irb(main):001:0> x ||= 7
=> 7
irb(main):002:0> x
=> 7

Brian A. wrote:

Are you sure about that?

[email protected]:~$ irb
irb(main):001:0> x ||= 7
=> 7
irb(main):002:0> x
=> 7

Sorry, you’re right. I’ve never tried this actually on an undefined
local variable - and I guessed it would first try to evaluate x, which
would raise an exception. Thanks for pointing that out, I’m happy to
have learnt it (:

mortee