in reply to Re^2: RFC: Placeholder creation for SQL statements
in thread RFC: Placeholder creation for SQL statements
nothing is leaking hereYour code is implemented with closures because they let you replace the closed over variables. That's fine. But those closures must be created by the user, so either the user understands that your code is creating a closure, and that's what I call a leak (calling the tool correctly is done by knowing how it's implemented), or the user doesn't know that and just knows that this is how the call must be written, because reasons (that's where you get into cargo cult territory).
I think your proposed version with ph is nearly fine though, becauses it kind of hides that exposed implementation detail, and it's easier to abstract away as a magic block where interpolation becomes placeholders, unlike the version with sub where advanced features of a common keyword are used.
You didn't answer my question about package vars though, which is one of the potential issues with using closures: if you don't know that this is what happens, you don't understand that you only have to use lexicals (assuming your code doesn't work with package vars).
Also, what would the following do, search for Eily twice or work as intended?
If they work as intended then the main issue might be package vars (unless your code works with them), and the fact that it looks like you have a more complicated syntax to do basically the same thing. That's again a good reason for ph { } rather than sub { }, several call to ph may work fine, but you have to be careful with sub. If it searches twice for Eily, this means that you have to understand how it works.my $username = 'LanX'; my $req1 = $db->xprepare(ph { "SELECT from users WHERE nick = '$userna +me'" }); $username = 'Eily'; my $req2 = $db->xprepare(ph { "SELECT from users WHERE nick = '$userna +me'" }); $req1->xexecute(); $req2->xexecute();
If you can ask your colleagues to change how the prepare is made, maybe you could do something like that instead:
That way it looks like a more classical command BLOCK PARAMS (except instead of setting $_ before each call, it sets %_). And then the values can be stored as members of the returned object, or closed over by a closure that will set %_ before calling &BLOCK(), ie the implementations details stay hidden.my %vars = (rank => 'Pope', xp => 4); my $req1 = $mytool->xprepare(ph { "SELECT from users WHERE rank = '$_{ +rank}' AND xp > '$_{xp}'" } %vars ); $req1->execute(); #There's no reason your new object can't call its me +thod execute BTW
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: RFC: Placeholder creation for SQL statements
by LanX (Saint) on Mar 09, 2018 at 19:20 UTC | |
by Eily (Monsignor) on Mar 10, 2018 at 00:27 UTC | |
by Eily (Monsignor) on Mar 10, 2018 at 00:37 UTC | |
by LanX (Saint) on Mar 10, 2018 at 02:22 UTC | |
by LanX (Saint) on Mar 10, 2018 at 17:40 UTC | |
by Eily (Monsignor) on Mar 12, 2018 at 18:56 UTC |