Anyone got a good one-liner?

D

D. Alvarado

I have a hash

%sqlUpdatePairs

whose key and value are both scalar strings. What I would like is a
resulting string, resembling

"COL1 = 'val1', COL2 = 'val2', COL3 = 'val3'"

assuming my hash had only 3 entries, referenced by the keys "COL1",
"COL2", and "COL3" whose respective values were "val1", "val2", and
"val3" (note that the values have no apostraphes).

Anyone know a one line (or at worst two line) way I can form the
desired string out of my hash?

Much apprecation - Dave
 
P

Paul Lalli

I have a hash

%sqlUpdatePairs

whose key and value are both scalar strings. What I would like is a
resulting string, resembling

"COL1 = 'val1', COL2 = 'val2', COL3 = 'val3'"

assuming my hash had only 3 entries, referenced by the keys "COL1",
"COL2", and "COL3" whose respective values were "val1", "val2", and
"val3" (note that the values have no apostraphes).

Anyone know a one line (or at worst two line) way I can form the
desired string out of my hash?

Much apprecation - Dave

print join(", ", map {"$_ = '$sqlUpdatePairs{$_}'"} keys %sqlUpdatePairs);

I'm willing to bet there are other, more efficient ways.

Paul Lalli
 
S

Steve (another one)

D. Alvarado said:
I have a hash

%sqlUpdatePairs

whose key and value are both scalar strings. What I would like is a
resulting string, resembling

"COL1 = 'val1', COL2 = 'val2', COL3 = 'val3'"

assuming my hash had only 3 entries, referenced by the keys "COL1",
"COL2", and "COL3" whose respective values were "val1", "val2", and
"val3" (note that the values have no apostraphes).

Anyone know a one line (or at worst two line) way I can form the
desired string out of my hash?

Much apprecation - Dave

for (keys(%sqlUpdatePairs)){$string.="$_ = '$sqlUpdatePairs{$_}', "}
 
P

Paul Lalli

for (keys(%sqlUpdatePairs)){$string.="$_ = '$sqlUpdatePairs{$_}', "}

This will add a trailing comma and space to the end of the string. That's
not what the OP asked for.

Paul Lalli
 
P

Peter Scott

I have a hash

%sqlUpdatePairs

whose key and value are both scalar strings. What I would like is a
resulting string, resembling

"COL1 = 'val1', COL2 = 'val2', COL3 = 'val3'"

assuming my hash had only 3 entries, referenced by the keys "COL1",
"COL2", and "COL3" whose respective values were "val1", "val2", and
"val3" (note that the values have no apostraphes).

Maybe today they don't, but why take the chance? There is a
more efficient way of doing this, assuming you are using DBI,
that doesn't care.
Anyone know a one line (or at worst two line) way I can form the
desired string out of my hash?

Using said more robust way (untested):

my @col_names = keys %sqlUpdatePairs;
my $sql = "UPDATE foo SET "
. join("," => map "$_ = ?" => @col_names)
. " WHERE blah";
my $sth = $dbh->prepare($sql);
#...
$sth->execute(@sqlUpdatePairs{@col_names});

Yes, it's more than one or two lines, although with some
uglification it could be compacted to that point. But
placeholders are the way to go with SQL and the DBI,
especially if you expect to execute the SQL many times.
 
J

John W. Krahn

D. Alvarado said:
I have a hash

%sqlUpdatePairs

whose key and value are both scalar strings. What I would like is a
resulting string, resembling

"COL1 = 'val1', COL2 = 'val2', COL3 = 'val3'"

assuming my hash had only 3 entries, referenced by the keys "COL1",
"COL2", and "COL3" whose respective values were "val1", "val2", and
"val3" (note that the values have no apostraphes).

Anyone know a one line (or at worst two line) way I can form the
desired string out of my hash?

Much apprecation - Dave


( $string = join( "\0", %sqlUpdatePairs ) . "'" ) =~ s/\0/ $|-- ? "', " : " = '" /eg;



John
 
H

Heinrich Mislik

Maybe today they don't, but why take the chance? There is a
more efficient way of doing this, assuming you are using DBI,
that doesn't care.


Using said more robust way (untested):

my @col_names = keys %sqlUpdatePairs;
my $sql = "UPDATE foo SET "
. join("," => map "$_ = ?" => @col_names)
. " WHERE blah";
my $sth = $dbh->prepare($sql);
#...
$sth->execute(@sqlUpdatePairs{@col_names});

This can be shorter (still untested):

my $sql = "UPDATE foo SET "
. join("," => map "$_ = ?" => keys %sqlUpdatePairs)
. " WHERE blah";
my $sth = $dbh->prepare($sql);
#...
$sth->execute(values %sqlUpdatePairs);

perldoc -f keys explicitly states that keys and values will use the same order.

Cheers

Heinrich Mislik
 
P

Peter Scott

This can be shorter (still untested):

my $sql = "UPDATE foo SET "
. join("," => map "$_ = ?" => keys %sqlUpdatePairs)
. " WHERE blah";
my $sth = $dbh->prepare($sql);
#...
$sth->execute(values %sqlUpdatePairs);

perldoc -f keys explicitly states that keys and values will use the same order.

....provided that the hash has not been modified in between. I was making no
assumptions about values being set during the "..." part of the code.
 
B

Brad Baxter

( $string = join( "\0", %sqlUpdatePairs ) . "'" ) =~ s/\0/ $|-- ? "', " : " = '" /eg;

Fascinating! I was wondering how to do that.

perl -le 'print $|-- for 1..5'
0
1
0
1
0

perl -le 'print $|=$_ for -2..2'
1
1
0
1
1

perl -le 'print $|++ for 1..5'
0
1
1
1
1

Apparently, setting $| to any non-zero value sets it to 1. I don't see
that behavior described in perlvar...

Regards,

Brad
 
P

Paul Lalli

Apparently, setting $| to any non-zero value sets it to 1. I don't see
that behavior described in perlvar...

Really? I see it...

"If set to nonzero, forces a flush right away and after every write or
print on the currently selected output channel. Default is 0 ..."

There's no difference between 1 and any other non-zero value. Why are you
thinking 1 is special?

Paul Lalli
 
B

Ben Morrow

Paul Lalli said:
Really? I see it...

"If set to nonzero, forces a flush right away and after every write or
print on the currently selected output channel. Default is 0 ..."

There's no difference between 1 and any other non-zero value. Why are you
thinking 1 is special?

No, his point is that this

perl -le'$| = 2; print $|'

prints 1, not 2. It kinda makes sense, but it isn't documented.

Ben
 
P

Paul Lalli

No, his point is that this

perl -le'$| = 2; print $|'

prints 1, not 2. It kinda makes sense, but it isn't documented.

Ohhh. My mistake. Apologies to Brad for that one.

Paul Lalli
 
B

Brad Baxter

Ohhh. My mistake. Apologies to Brad for that one.

Not a problem. I'm also not sure that I'm recommending the docs be
changed, but the following thoughts occurred to me.

o It makes me think that the value of $| is stored internally as a bit.

o Any use of $| as a boolean flip-flop beyond one-liners and/or
obfuscation is questionable at best.

o If anyone is using it like this in production code anyway, how likely is
$|'s behavior in this regard likely to change and break such code?

o This behavior is not what a Perl programmer would expect. Though Perl
programmers often expect magic, so maybe I'm wrong. :)

o Knowing it's either 1 or 0, one might be inclined to think 'true' and
'false', but _some_ of Perl's normal ideas of truth and falsehood don't
apply:

$| = '0 but true' # false here, but true elsewhere
$| = 'alpha string' # same

o the docs say, "If set to nonzero", and 'hey' is nonzero, but
$| = 'hey' will not set $| to 1

o if the behavior never changes ++$| is guaranteed to always be 1

I did some cursory unsuccessful searches for earlier discussions about
this but still I might be walking packed earth. And I suspect this is,
for the most part, a non-problem. But it is a curiosity.

Regards,

Brad
 
J

John W. Krahn

Brad said:
Not a problem. I'm also not sure that I'm recommending the docs be
changed, but the following thoughts occurred to me.

o It makes me think that the value of $| is stored internally as a bit.

That was my understanding, but I could be wrong. It certainly acts like
a one bit variable.
o Any use of $| as a boolean flip-flop beyond one-liners and/or
obfuscation is questionable at best.
Definitely.

o If anyone is using it like this in production code anyway, how likely is
$|'s behavior in this regard likely to change and break such code?

o This behavior is not what a Perl programmer would expect. Though Perl
programmers often expect magic, so maybe I'm wrong. :)

No, this is completely expected behavior. :)
o Knowing it's either 1 or 0, one might be inclined to think 'true' and
'false', but _some_ of Perl's normal ideas of truth and falsehood don't
apply:

$| = '0 but true' # false here, but true elsewhere
$| = 'alpha string' # same

A string in numerical context evaluates to zero unless there is a number
at the beginning of the string.

$ perl -le'
for ( "some string",
"99some string",
"99 some string",
" 99 some string" ) {
print $_ + 0; # numerical context
}
'
0
99
99
99
o the docs say, "If set to nonzero", and 'hey' is nonzero, but
$| = 'hey' will not set $| to 1

'hey' in numerical context IS zero.
o if the behavior never changes ++$| is guaranteed to always be 1

Yes.


John
 
B

Ben Morrow

John W. Krahn said:
That was my understanding, but I could be wrong. It certainly acts like
a one bit variable.

No. If it was a one bit variable then

$| = 1; $|++;

would overflow to 0 again. Assigning to $| is more like calling

sub set_dollarpipe {
$| = (0 + $_[0]) ? 1 : 0;
}

..

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top