Rob Lally
4/13/2005 8:19:00 PM
Jamis Buck wrote:
> On Apr 13, 2005, at 11:08 AM, Rob Lally wrote:
>
>> Hi,
>>
>> I've been using Needle to try to create an iBatis like framework in
>> Ruby. I want register parameterized blocks but when I do this they
>> have to take the container and service point as the first two
>> parameters. At least I think they need to ... I'm hoping they don't,
>> can anyone suggest a way round it?
>>
>
> First off, I'm not familiar at all with iBatis--could you give a little
> background on that? I'm also not entirely sure I understand what you're
> asking, but I *think* you're saying the following:
iBatis is an OR mapping tool from the Java world based on the DAO pattern. I mentioned it more for colour than because
it was useful information. How I expected anyone else to know that I'm not sure ...
> registry.register(:my_service, :model => :multiton) do |c,p,*args|
> # do something with *args, like:
> args.map { |i| "sing: #{i}" }
> end
>
> And you want to be able to register a block that does NOT use the first
> two parameters for "c" (the container) and "p" (the service point), right?
>
> Please keep in mind that even though the block accepts those first two
> parameters, the service point itself is parameterized only on the
> remaining values. In other words, when you go to query the "my_service"
> service, you do NOT pass in the "c" and "p" arguments--Needle does that
> for you. Thus:
>
> my_service = registry.my_service("do", "re", "mi")
> p my_service
>
> Would print
>
> ["sing: do", "sing: re", "sing: mi"]
>
> Does that make sense? Or did I miss the gist of your question?
For this particular framework the container and service point are not likely ever to be useful to the party writing the
blocks; it is using Needle "under the covers" rather than as a top level object. So if the client wants to write
parameterized blocks they would need to include two mystery parameters. When I say mystery parameters I only mean
because the use of Needle under the covers isn't transparent.
Perhaps some code would be clearer:
A user of the framework would write
mapr.register_statement(:select_person_by_id) do |id|
"SELECT * FROM person WHERE id = #{id}"
end
Under the covers this stores this block in a needle registry. In order to be able to call the service with a parameter
it would need to have c and p at the start of the block parameter list.
At the moment I'm wrapping this block under the cover with another block
def register_statement(name, &statement)
@registry.statements.register(name, :model => :prototype) {|c, p, *args| statement.call(*args) }
end
Which works fine but feels a bit off.
I was hoping that there would be an option looking like:
def register_statement(name, &statement)
@registry.statements.register(name, :model => :prototype, :container_agnostic => true, &statement)
end
Which would enable parameterised services that don't get the c and p parameters.
Thanks for taking the time to respond.
R.