http://www.perlmonks.org?node_id=17466

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question: (object-oriented programming)

I want to have a double-quoted string like this, where $dbh is a DBI database handle and $userinput is (potentially hostile) user input:

"select * from foo where bar = $dbh->quote($userinput)"
It doesn't work. That quote method isn't called. Instead, the $dbh object itself is converted to a string.

This works like I want:

"select foo from bar where baz = ${ \$dbh->quote($userinput) }"
But that is an ugly hack, referencing and dereferencing just to trick Perl's string parser into doing what I want.

Any better ideas? I know I can do "blah".$whatever."blah" but that's even harder for my eyes to parse.

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: Calling a method within a double-quoted string?
by plaid (Chaplain) on Jun 10, 2000 at 04:11 UTC

    You should use place holders in this case, as they automatically take care of quoting:

    my $sth = $dbh->prepare("select * from foo where bar = ?"); $sth->execute($userinput);
    In the more general case, you can use sprintf to interpolate functions into strings:
    my $sql = sprintf "select * from foo where bar = %s", $dbh->quote($use +rinput);

Re: Calling a method within a double-quoted string?
by btrott (Parson) on Jun 10, 2000 at 04:15 UTC

    For the DBI case, the correct answer is definitely placeholders.

    However, in the general case, consider Interpolation. It's pretty nifty. It lets you define "arbitrary interpolation semantics".

    From its man page:

    For example, you can say use Interpolation money => \&commify_with_dollar_sign, E => 'eval', placename => 'ucwords'; And then you can write these: print "3 + 4 = $E{3+4}"; # Prints ``3 + 4 = 7'' $SALARY = 57500; print "The salary is $money{$SALARY}"; # Prints ``The salary is $57,500.00''
    For your need, you could use this:
    use vars qw/$dbh/; use DBI; $dbh = DBI->connect('baz', 'foo', 'bar', 'Oracle'); use Interpolation quoteit => sub { $dbh->quote(@_) }; print "select * from foo where bar = $quoteit{baz}";
    Which is quite handy. Still, in your particular case, placeholders are better.

Re: Calling a method within a double-quoted string?
by pemungkah (Priest) on Nov 08, 2006 at 01:56 UTC
    The cheap but punctuation-heavy answer:
    my $string = "this is an interpolated method call: @{[$obj->method]}";
    What's happening here, working from the inside out:
    1. The method call happens, and it returns a list of zero or more values.
    2. Outside that, we have an anonymous array constructor, so now we've got a reference to an anonymous array containing the value(s) returned from the method.
    3. Outside that, we have @{ }, which dereferences the array reference, so we have an array.
    4. Perl now happily interpolates the dynamically-generated anonymous array into the string, because it knows how to do that.
    This is essentially what Interpolation.pm does, cut down to adding a few extra characters in your string. Drawback: ugly, and possibly really confusing to the reader. Advantage: only 5 extra characters.
Answer: Calling a method within a double-quoted string?
by Anonymous Monk on Jun 10, 2000 at 04:32 UTC

    Thanks folks! I already knew about placeholders but not all DBI drivers support them.

    I always forget about sprintf. I guess I don't like seperating variables from the string.

    Interpolation.pm looks really cool. I'll have to try it.

      The Anonymous Monk said:
      > I already knew about placeholders but not all DBI > drivers support them.
      Actually, I believe placeholders are at least emulated in all DBI drivers. Even if the underlying database doesn't support placeholders or bound variables, DBI emulates the behavior internally. This is true, at least, of the MySQL driver. The appendix of the DBI book has more information.