Re: Huh? 4=3?

2013-05-09 Thread Tim Bunce
On Wed, May 08, 2013 at 10:58:02AM -0700, fe...@crowfix.com wrote:
> On Wed, May 08, 2013 at 09:43:27AM -0700, Bill Ward wrote:
> > Cool. That whole scalar vs list context thing is one of Perl's biggest
> > strengths, but also one of its biggest weaknesses (in that it is a common
> > source of bugs like this). When you see head-scratching problems, it's one
> > of the first things to look for.
> 
> Just guessing here, not familiar with the particular code in question.
> But I have been bitten a few times by code which returns false in the
> 'proper' manner
> 
> return;
> 
> instead of forcing a scalar return
> 
> return undef;
> 
> or list return
> 
> return ();

There is no difference between "return;" and "return ();".
Both return an empty list when called in list context
and an undef when called in scalar context.

The "return ();" style does serve as a reminder to the reader.

> Is that what's going on here -- the original code imparted a list
> context, which triggered another perl gotcha, whereby missing list
> values simply disappear:
> 
> scalar(1,2,,4,,6) ---> 4, not 6

That returns 6, or rather, it returns whatever happens to be the last value.

Tim.


Re: Huh? 4=3?

2013-05-08 Thread Derek Jones
Hi all,

> 
> You are right -- but this produces 4 first, as I had always thought it
> would, and then 6, as I don't quite understand.  I would never use
> that kind of expression, and I sorta maybe understand why it says 6,
> but only in hindsight.
> 
> #!/usr/bin/perl
> 
> my @ary = (1,2,,4,,6);
> print "Step 1: ", scalar(@ary), "\n";
> print "Step 2: ", scalar(1,2,,4,,6), "\n";

In the first example, scalar is operating on the array to give you its size. So 
you do indeed get 4, because only 4 elements are allocated. That is *indeed* an 
unusual and somewhat apparently counterintutive feature since very often in 
Perl, otherwise "undefined values" have storage autovifified when assigned 
under the hood and if interrogated with the defined operator will give you 
false. i.e. "the box is there but empty".

If you want to tell if the element is there at all - you can use exists.

E.g. 

print "Hi there element 4\n" if exists $ary[4];
print "Hi there element 5\n" if exists $ary[5];

which - in the case of @ary above would not print anything since only elements 
0..3 exist.

If you wanted 6 elements, as was noted earlier, you would have to preserve the 
indexing of the "missing" elements by using undef (see below).

In the 2nd example, as we've noted, - you are simply getting the last value in 
a list - 6  in this case.

So, the question is - why does Perl not keep the otherwise "undefined" elements 
in the list when they are being represented by ,, ?

And the answer is unusual in that it's still seeing 

my @ary = (1,2,,4,,6);

as a sequence on the right hand side - in which there are only 4 scalar items.

So, to make it have 6, you'd say:

my @ary = (1,2,undef,4,undef,6);

That will autovivify all 6 elements, each of which will exist now according to 
exists, but only 4 of which will have defined values according to defined.

Here's an updated version of your example:

--

#!/usr/bin/perl

print "Original\n";

my @ary = (1,2,,4,,6);

print "Step 1: ", scalar(@ary), "\n";
print "Step 2: ", scalar(1,2,,4,,6), "\n";

print "Hi there element 4\n" if exists $ary[4]; # Does not print
print "Hi there element 5\n" if exists $ary[5]; # Does not print

print "New\n";

my @ary2 = (1,2,undef,4,undef,6);

print "Step 1: ", scalar(@ary2), "\n";
print "Step 2: ", scalar(1,2,undef,4,undef,6), "\n";

print "Hi there element 4\n" if exists $ary2[4];  #Now prints
print "Hi there element 5\n" if exists $ary2[5]   #Now prints


--

This is somewhat counterintuitive in that, if you had an array where you 
specified the size of a slice on the left, Perl would automatically allocate 
that number of elements and automatically assign undef to the ones not 
otherwise filled. But…. not in the way you expect.

E.g.

@ary3[0..5] = (1,2,,4,,6);

Does *not* preserve the gaps - for the exact same reason as above. But, you do 
get elements 4 and 5 now - but it's *those* that are undef - and the actual 
list (1,2,4,6) gets assigned to elements 0..3

E.g.


print "New2\n";

my @ary3;

@ary3[0..5] = (1,2,,4,,6);

print "Size: ", scalar(@ary3), "\n";

print "Hi there element 4\n" if exists $ary3[4];  #Prints
print "Hi there element 5\n" if exists $ary3[5];  #Prints

print "Hidef 4\n" if defined $ary3[4];  #Does not print
print "Hidef 5\n" if defined $ary3[5];  #Does not print


$"=":";

print "Elements\n";

print "-->@ary3<--\n";   # Notice the empty (undefined) two elements at the 
*end*… ;-)

Kind regards

Derek.



Re: Huh? 4=3?

2013-05-08 Thread felix
On Wed, May 08, 2013 at 06:22:09PM -0700, James Marshall wrote:
> It shows 6 because a comma-separated literal list, when interpreted as a
> scalar, evaluates to the final value in the list, not the length of the
> list.  If you evaluate "scalar(1,2,,4,,7)", it will equal 7.  That's the
> comma operator at work-- even though it looks like a list (and both use
> commas), it's really just a sequential set of expressions.

I think I've forgotten more useless perl trivia than I should have...
I use the comma operator sometimes, but never inside scalar().  Didn't
recognize it.  TMTOWTMakeAMess.

-- 
... _._. ._ ._. . _._. ._. ___ .__ ._. . .__. ._ .. ._.
 Felix Finch: scarecrow repairman & rocket surgeon / fe...@crowfix.com
  GPG = E987 4493 C860 246C 3B1E  6477 7838 76E9 182E 8151 ITAR license #4933
I've found a solution to Fermat's Last Theorem but I see I've run out of room o


Re: Huh? 4=3?

2013-05-08 Thread James Marshall
It shows 6 because a comma-separated literal list, when interpreted as a
scalar, evaluates to the final value in the list, not the length of the
list.  If you evaluate "scalar(1,2,,4,,7)", it will equal 7.  That's the
comma operator at work-- even though it looks like a list (and both use
commas), it's really just a sequential set of expressions.

Cheers,
James


On Wed, May 8, 2013 at 5:14 PM,  wrote:

> On Wed, May 08, 2013 at 02:04:37PM -0400, Derek Jones wrote:
> > Huh?
> >
> > That produces 6 - as it should. What version of Perl are you working
> with?
>
> > On May 8, 2013, at 1:58 PM, fe...@crowfix.com wrote:
> >
> > > scalar(1,2,,4,,6)
>
> You are right -- but this produces 4 first, as I had always thought it
> would, and then 6, as I don't quite understand.  I would never use
> that kind of expression, and I sorta maybe understand why it says 6,
> but only in hindsight.
>
> #!/usr/bin/perl
>
> my @ary = (1,2,,4,,6);
> print "Step 1: ", scalar(@ary), "\n";
> print "Step 2: ", scalar(1,2,,4,,6), "\n";
>
> --
> ... _._. ._ ._. . _._. ._. ___ .__ ._. . .__. ._ .. ._.
>  Felix Finch: scarecrow repairman & rocket surgeon / fe...@crowfix.com
>   GPG = E987 4493 C860 246C 3B1E  6477 7838 76E9 182E 8151 ITAR license
> #4933
> I've found a solution to Fermat's Last Theorem but I see I've run out of
> room o
>


Re: Huh? 4=3?

2013-05-08 Thread felix
On Wed, May 08, 2013 at 02:04:37PM -0400, Derek Jones wrote:
> Huh?
> 
> That produces 6 - as it should. What version of Perl are you working with?

> On May 8, 2013, at 1:58 PM, fe...@crowfix.com wrote:
> 
> > scalar(1,2,,4,,6) 

You are right -- but this produces 4 first, as I had always thought it
would, and then 6, as I don't quite understand.  I would never use
that kind of expression, and I sorta maybe understand why it says 6,
but only in hindsight.

#!/usr/bin/perl

my @ary = (1,2,,4,,6);
print "Step 1: ", scalar(@ary), "\n";
print "Step 2: ", scalar(1,2,,4,,6), "\n";

-- 
... _._. ._ ._. . _._. ._. ___ .__ ._. . .__. ._ .. ._.
 Felix Finch: scarecrow repairman & rocket surgeon / fe...@crowfix.com
  GPG = E987 4493 C860 246C 3B1E  6477 7838 76E9 182E 8151 ITAR license #4933
I've found a solution to Fermat's Last Theorem but I see I've run out of room o


Re: Huh? 4=3?

2013-05-08 Thread Chad Wallace
On Wed, 8 May 2013 09:30:18 -0700
Bill Ward  wrote:

> My guess is that get_value() is returning an empty array rather than
> an undef scalar when the values are null. Try copying each one to a
> scalar variable and including the list of variables in the execute().
> It'd be more readable that way anyway. Or if you must put them all
> one one line like this, add the scalar() function on each argument.

I use this idiom:

... get_value(...) || undef, ...get_value(...) || undef, ...

If you don't want undef, you can use "|| ''" or "|| 0" instead.


> On Wed, May 8, 2013 at 9:18 AM, Bruce Johnson
> wrote:
> 
> > Getting the error:
> >
> > DBD::Oracle::st execute failed: called with 3 bind variables when 4
> > are needed [for Statement "insert into employee_fte_annualrate_l
> > (emplid, emptype_cd, fte, annual_rate) values(?,?,?,?)" with
> > ParamValues: :p1='22057713', :p2='R', :p3='1', :p4='47311']
> > at /home/oraweb/perl/frs/ kfsupdate.pl line 64,  line 581.
> >
> > I'm pretty sure I count 4 placeholders and 4 parameter values in
> > that error message, so where is the '3 bind variables' coming from?
> >
> > here's the cursor definition:
> >
> > my $csr_emp_info = $lda->prepare("insert into
> > employee_fte_annualrate_l (emplid, emptype_cd, fte, annual_rate)
> > values(?,?,?,?)");
> >
> > I'm pulling the data from an LDAP query, here's the offending line
> > 64 (where $mesg is the returned LDAP object):
> >
> > $csr_emp_info->execute($mesg->entry($n)->get_value('emplId'),
> > $mesg->entry($n)->get_value('employeeType'),$mesg->entry($n)->get_value('employeeFTE'),$mesg->entry($n)->get_value('employeeTotalAnnualRate'));
> >
> > All the columns allow null entries, and these are all single-valued
> > entries in the LDAP schema.
> >
> >
> > --
> > Bruce Johnson
> > University of Arizona
> > College of Pharmacy
> > Information Technology Group
> >
> > Institutions do not have opinions, merely customs
> >
> >
> >
> 
> 


-- 

C. Chad Wallace, B.Sc.
The Lodging Company
http://www.lodgingcompany.com/
OpenPGP Public Key ID: 0x262208A0



Re: Huh? 4=3?

2013-05-08 Thread Bruce Johnson

On May 8, 2013, at 10:58 AM, fe...@crowfix.com wrote:

> 
> Is that what's going on here -- the original code imparted a list
> context, which triggered another perl gotcha, whereby missing list
> values simply disappear:
> 

And I remember now the reason the error message is confusing, I'll bet that was 
an actual bug I discovered in (iirc) DBI or DBD::Oracle which was fixed, but 
not on this particular server, because we're still constrained to running a 
very old version for various reasons. The error message actually displays the 
values for the last successful insert not the one that failed.

Mystery now solved.

-- 
Bruce Johnson
University of Arizona
College of Pharmacy
Information Technology Group

Institutions do not have opinions, merely customs




Re: Huh? 4=3?

2013-05-08 Thread felix
On Wed, May 08, 2013 at 09:43:27AM -0700, Bill Ward wrote:
> Cool. That whole scalar vs list context thing is one of Perl's biggest
> strengths, but also one of its biggest weaknesses (in that it is a common
> source of bugs like this). When you see head-scratching problems, it's one
> of the first things to look for.

Just guessing here, not familiar with the particular code in question.
But I have been bitten a few times by code which returns false in the
'proper' manner

return;

instead of forcing a scalar return

return undef;

or list return

return ();

Is that what's going on here -- the original code imparted a list
context, which triggered another perl gotcha, whereby missing list
values simply disappear:

scalar(1,2,,4,,6) ---> 4, not 6

I understand and appreciate most of Perl's little tricks, but they
sometimes catch me by surprise and elicit a few curses while debugging.

-- 
... _._. ._ ._. . _._. ._. ___ .__ ._. . .__. ._ .. ._.
 Felix Finch: scarecrow repairman & rocket surgeon / fe...@crowfix.com
  GPG = E987 4493 C860 246C 3B1E  6477 7838 76E9 182E 8151 ITAR license #4933
I've found a solution to Fermat's Last Theorem but I see I've run out of room o


Re: Huh? 4=3?

2013-05-08 Thread Bill Ward
Cool. That whole scalar vs list context thing is one of Perl's biggest
strengths, but also one of its biggest weaknesses (in that it is a common
source of bugs like this). When you see head-scratching problems, it's one
of the first things to look for.


On Wed, May 8, 2013 at 9:39 AM, Bruce Johnson
wrote:

> Well, changing the code to:
>
> my $eid=$mesg->entry($n)->get_value('emplId');
> my $etp=$mesg->entry($n)->get_value('employeeType');
> my $efte=$mesg->entry($n)->get_value('employeeFTE');
> my $ear=$mesg->entry($n)->get_value('employeeTotalAnnualRate');
>
> $csr_emp_info->execute($eid,$etp,$efte,$ear);
>
> like you suggested fixed it.
>
> Thanks.
>
> On May 8, 2013, at 9:30 AM, Bill Ward  wrote:
>
> > My guess is that get_value() is returning an empty array rather than an
> undef scalar when the values are null. Try copying each one to a scalar
> variable and including the list of variables in the execute(). It'd be more
> readable that way anyway. Or if you must put them all one one line like
> this, add the scalar() function on each argument.
> >
> >
> > On Wed, May 8, 2013 at 9:18 AM, Bruce Johnson <
> john...@pharmacy.arizona.edu> wrote:
> > Getting the error:
> >
> > DBD::Oracle::st execute failed: called with 3 bind variables when 4 are
> needed [for Statement "insert into employee_fte_annualrate_l (emplid,
> emptype_cd, fte, annual_rate) values(?,?,?,?)" with ParamValues:
> :p1='22057713', :p2='R', :p3='1', :p4='47311'] at /home/oraweb/perl/frs/
> kfsupdate.pl line 64,  line 581.
> >
> > I'm pretty sure I count 4 placeholders and 4 parameter values in that
> error message, so where is the '3 bind variables' coming from?
> >
> > here's the cursor definition:
> >
> > my $csr_emp_info = $lda->prepare("insert into employee_fte_annualrate_l
> (emplid, emptype_cd, fte, annual_rate) values(?,?,?,?)");
> >
> > I'm pulling the data from an LDAP query, here's the offending line 64
> (where $mesg is the returned LDAP object):
> >
> > $csr_emp_info->execute($mesg->entry($n)->get_value('emplId'),
> $mesg->entry($n)->get_value('employeeType'),$mesg->entry($n)->get_value('employeeFTE'),$mesg->entry($n)->get_value('employeeTotalAnnualRate'));
> >
> > All the columns allow null entries, and these are all single-valued
> entries in the LDAP schema.
> >
> >
> > --
> > Bruce Johnson
> > University of Arizona
> > College of Pharmacy
> > Information Technology Group
> >
> > Institutions do not have opinions, merely customs
> >
> >
> >
> >
> >
> > --
> > Check out my LEGO blog at brickpile.com
> > Follow/friend me: Facebook • Flickr • Twitter • LinkedIn
>
> --
> Bruce Johnson
> University of Arizona
> College of Pharmacy
> Information Technology Group
>
> Institutions do not have opinions, merely customs
>
>
>


-- 
Check out my LEGO blog at brickpile.com 
Follow/friend me: Facebook  •
Flickr•
Twitter  •
LinkedIn


Re: Huh? 4=3?

2013-05-08 Thread Bruce Johnson
Well, changing the code to:

my $eid=$mesg->entry($n)->get_value('emplId');
my $etp=$mesg->entry($n)->get_value('employeeType');
my $efte=$mesg->entry($n)->get_value('employeeFTE');
my $ear=$mesg->entry($n)->get_value('employeeTotalAnnualRate');

$csr_emp_info->execute($eid,$etp,$efte,$ear);

like you suggested fixed it.

Thanks.

On May 8, 2013, at 9:30 AM, Bill Ward  wrote:

> My guess is that get_value() is returning an empty array rather than an undef 
> scalar when the values are null. Try copying each one to a scalar variable 
> and including the list of variables in the execute(). It'd be more readable 
> that way anyway. Or if you must put them all one one line like this, add the 
> scalar() function on each argument.
> 
> 
> On Wed, May 8, 2013 at 9:18 AM, Bruce Johnson  
> wrote:
> Getting the error:
> 
> DBD::Oracle::st execute failed: called with 3 bind variables when 4 are 
> needed [for Statement "insert into employee_fte_annualrate_l (emplid, 
> emptype_cd, fte, annual_rate) values(?,?,?,?)" with ParamValues: 
> :p1='22057713', :p2='R', :p3='1', :p4='47311'] at 
> /home/oraweb/perl/frs/kfsupdate.pl line 64,  line 581.
> 
> I'm pretty sure I count 4 placeholders and 4 parameter values in that error 
> message, so where is the '3 bind variables' coming from?
> 
> here's the cursor definition:
> 
> my $csr_emp_info = $lda->prepare("insert into employee_fte_annualrate_l 
> (emplid, emptype_cd, fte, annual_rate) values(?,?,?,?)");
> 
> I'm pulling the data from an LDAP query, here's the offending line 64 (where 
> $mesg is the returned LDAP object):
> 
> $csr_emp_info->execute($mesg->entry($n)->get_value('emplId'), 
> $mesg->entry($n)->get_value('employeeType'),$mesg->entry($n)->get_value('employeeFTE'),$mesg->entry($n)->get_value('employeeTotalAnnualRate'));
> 
> All the columns allow null entries, and these are all single-valued entries 
> in the LDAP schema.
> 
> 
> --
> Bruce Johnson
> University of Arizona
> College of Pharmacy
> Information Technology Group
> 
> Institutions do not have opinions, merely customs
> 
> 
> 
> 
> 
> -- 
> Check out my LEGO blog at brickpile.com
> Follow/friend me: Facebook • Flickr • Twitter • LinkedIn

-- 
Bruce Johnson
University of Arizona
College of Pharmacy
Information Technology Group

Institutions do not have opinions, merely customs




Re: Huh? 4=3?

2013-05-08 Thread Bill Ward
My guess is that get_value() is returning an empty array rather than an
undef scalar when the values are null. Try copying each one to a scalar
variable and including the list of variables in the execute(). It'd be more
readable that way anyway. Or if you must put them all one one line like
this, add the scalar() function on each argument.


On Wed, May 8, 2013 at 9:18 AM, Bruce Johnson
wrote:

> Getting the error:
>
> DBD::Oracle::st execute failed: called with 3 bind variables when 4 are
> needed [for Statement "insert into employee_fte_annualrate_l (emplid,
> emptype_cd, fte, annual_rate) values(?,?,?,?)" with ParamValues:
> :p1='22057713', :p2='R', :p3='1', :p4='47311'] at /home/oraweb/perl/frs/
> kfsupdate.pl line 64,  line 581.
>
> I'm pretty sure I count 4 placeholders and 4 parameter values in that
> error message, so where is the '3 bind variables' coming from?
>
> here's the cursor definition:
>
> my $csr_emp_info = $lda->prepare("insert into employee_fte_annualrate_l
> (emplid, emptype_cd, fte, annual_rate) values(?,?,?,?)");
>
> I'm pulling the data from an LDAP query, here's the offending line 64
> (where $mesg is the returned LDAP object):
>
> $csr_emp_info->execute($mesg->entry($n)->get_value('emplId'),
> $mesg->entry($n)->get_value('employeeType'),$mesg->entry($n)->get_value('employeeFTE'),$mesg->entry($n)->get_value('employeeTotalAnnualRate'));
>
> All the columns allow null entries, and these are all single-valued
> entries in the LDAP schema.
>
>
> --
> Bruce Johnson
> University of Arizona
> College of Pharmacy
> Information Technology Group
>
> Institutions do not have opinions, merely customs
>
>
>


-- 
Check out my LEGO blog at brickpile.com 
Follow/friend me: Facebook  •
Flickr•
Twitter  •
LinkedIn


Huh? 4=3?

2013-05-08 Thread Bruce Johnson
Getting the error:

DBD::Oracle::st execute failed: called with 3 bind variables when 4 are needed 
[for Statement "insert into employee_fte_annualrate_l (emplid, emptype_cd, fte, 
annual_rate) values(?,?,?,?)" with ParamValues: :p1='22057713', :p2='R', 
:p3='1', :p4='47311'] at /home/oraweb/perl/frs/kfsupdate.pl line 64,  
line 581.

I'm pretty sure I count 4 placeholders and 4 parameter values in that error 
message, so where is the '3 bind variables' coming from?

here's the cursor definition:

my $csr_emp_info = $lda->prepare("insert into employee_fte_annualrate_l 
(emplid, emptype_cd, fte, annual_rate) values(?,?,?,?)");

I'm pulling the data from an LDAP query, here's the offending line 64 (where 
$mesg is the returned LDAP object):

$csr_emp_info->execute($mesg->entry($n)->get_value('emplId'), 
$mesg->entry($n)->get_value('employeeType'),$mesg->entry($n)->get_value('employeeFTE'),$mesg->entry($n)->get_value('employeeTotalAnnualRate'));

All the columns allow null entries, and these are all single-valued entries in 
the LDAP schema.


-- 
Bruce Johnson
University of Arizona
College of Pharmacy
Information Technology Group

Institutions do not have opinions, merely customs