From: Rob Lally Date: 2005-04-14T05:19:06+09:00 Subject: Re: Needle and Parameterized Services 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.