Hi,
I am using JRuby to access data in some business application (Siebel,
if anybody is interested).
In Siebel I need to activate fields if I want to access them later:
bc.activate_field(name)
bc.query(search_specs)
do stuff
I’ve written methods that do the query and then yield each record to a
given block, so I can write something like:
bc.activate_field(“field1”)
bc.activate_field(“field2”)
bc.find_all(search_specs) do |record|
record[“field1”] = “some value”
puts record[“field2”]
end
I would like to do the activate_field() calls automatically, based on
which fields are being accessed inside the block.
Is it possible to look into the block and find out which fields are
being accessed? In the above example that would include the fields
“field1” and “field2”.
Basically, can I access the code inside the block and inspect it?
Thomas
On Tue, Mar 4, 2008 at 3:00 PM, Thomas M.
[email protected] wrote:
I’ve written methods that do the query and then yield each record to a
which fields are being accessed inside the block.
Is it possible to look into the block and find out which fields are
being accessed? In the above example that would include the fields
“field1” and “field2”.
Basically, can I access the code inside the block and inspect it?
I don’t know of any way to do that. But I don’t think you need to:
you can yield a proxy object to the block that intercepts the
references (the []= methods on the record object, or anything else
that requires activation) and activates fields as necessary, before
passing the call on to the object that does the real work, I think.
Thanks for your quick reply. If I understand you correctly that would
result in something like this being executed:
bc.find_all(search_specs) do |record|
activate(“field1”) # this is what the proxy object would do
record[“field1”] = “some value”
activate(“field2”) # this is what the proxy object would do
puts record[“field2”]
end
That wouldn’t work because the fields need to be activated before I
query the data, basically before or at the beginning of the find_all()
method.
When I query for data in Siebel it issues SQL statements to the
database and only includes activated fields. Activating fields just
before accessing them doesn’t work - they need to be activated before
querying the database.
My find_all() looks something like this:
def find_all
self.clear_to_query()
self.set_search_spec(…) # several of those, based on arguments to
find_all()
self.execute_query()
begin
yield self
end while self.next_record() if self.first_record()
end
The fields need to be activated before the execute_query() call.
Thomas
2008/3/5, Christopher D. [email protected]:
On Tue, Mar 4, 2008 at 4:56 PM, Thomas M.
[email protected] wrote:
The fields need to be activated before the execute_query() call.
Hmm. That’s trickier. You could create an method on some convenient
class
(or object) from the block with define_method, and then use ParseTree to
get
the parse tree of that method, and walk through the resulting
s-expression to
find out which fields are called. Though if any of the fields are
determined
dynamically, that won’t work, because you won’t have the results of the
dynamic determination, just the parse tree of the code that would get
it.
(My ParseTree-fu isn’t strong enough to sketch out code to demonstrate
that,
but conceptually, with the caveat about dynamic determination of fields,
it seems at least possible.)
Thomas M. wrote:
I’ve written methods that do the query and then yield each record to a
which fields are being accessed inside the block.
Is it possible to look into the block and find out which fields are
being accessed? In the above example that would include the fields
“field1” and “field2”.
Basically, can I access the code inside the block and inspect it?
Thomas
bc.find_all(search_specs,‘field1’,‘field2’) { |record,fields|
record[field[0]] = “some value”
puts record[field[1]]
}
On Mar 4, 8:54 pm, William J. [email protected] wrote:
I would like to do the activate_field() calls automatically, based on
puts record[field[1]]}
A couple of s’s were missing.
bc.find_all(search_specs,‘field1’,‘field2’) { |record,fields|
record[fields[0]] = “some value”
puts record[fields[1]]}
I think that’ll be sufficient. My goal is to make it easy for the user
(which is mainly myself) to be lazy and activate the fields
automatically. If I can’t capture the usage of some fields sometimes
then those fields can still manually be activated.
I’m already installing ParseTree and will try that out. Looks promising.
Thanks a lot.
2008/3/5, Christopher D. [email protected]:
On Mar 4, 4:56 pm, Thomas M. [email protected]
wrote:
That wouldn’t work because the fields need to be activated before I
query the data, basically before or at the beginning of the find_all()
method.
end
You could instead yield to the given block /before/ doing the actual
query and pass in an object which would simply record the method
calls. Then you could figure out the fields that need to be activated
from that, do the query, and replay the method calls on the actual
records returned. This would get difficult if you tried to do anything
beyond basic one-liners within the block, but it might work.
–
Regards,
John W.
2008/3/5, William J. [email protected]:
bc.find_all(search_specs,‘field1’,‘field2’) { |record,fields|
record[fields[0]] = “some value”
puts record[fields[1]]}
That would work but the user would still have to identify the fields
that need to be activated. I’d rather have that done automatically.
Thanks anyways.