newbie-ish question

J

Jack

I am confused about how I can detect if the function jack has returned
an UNDEFined value;

note that I don't want to catch the return from 'jack' in a single
variable @array, rather I want it to return the seperate values, as
indicated.

Is there a way to detect if 'jack' returns undef (or null or
whatever), without first catching it in an @array variable.

The code below produces this:
$ perl test
defined(@array) is deprecated at test line 14.
(Maybe you should just omit the defined()?)
the return from jack() is 0, 3.14159, Lemmings, all of them!
$

but if I remove the 'defined' and change jack to return an 'undef', I
get this:
$ perl test
Useless use of private variable in void context at test line 8.
Useless use of private variable in void context at test line 8.
Useless use of private variable in void context at test line 8.
Use of uninitialized value in concatenation (.) or string at test line
16.
Use of uninitialized value in concatenation (.) or string at test line
16.
Use of uninitialized value in concatenation (.) or string at test line
16.
the return from jack() is , ,
$


////////////////////////////////////////////////////////////
use strict;
use warnings;

sub jack{
my $int1 = 0;
my $float1 = 3.14159;
my $string = "Lemmings, all of them!";
($int1, $float1, $string);
};

my $num;
my $flt;
my $str;
if( defined(($num, $flt, $str) = jack)){
print "the return from jack() is $num, $flt, $str \n";
}
else{
print "return was undef";
}
////////////////////////////////////////////////////////////
 
P

Paul Lalli

Jack said:
I am confused about how I can detect if the function jack has returned
an UNDEFined value;

The function jack will NEVER return an undefined value. It will always
return exactly three values. And with the code you've shown, those
three values will always be defined values. I will assume for the
remainder of this post that your actual function returns three values
which may or may not be defined. (Have you read the Posting Guidelines
for this group? Please post real code.)
note that I don't want to catch the return from 'jack' in a single
variable @array, rather I want it to return the seperate values, as
indicated.

Is there a way to detect if 'jack' returns undef (or null or
whatever), without first catching it in an @array variable.

The use of the word 'whatever' indicates a severe lack of understanding,
and unfortunately implies a lack of caring to learn the correct
terminology. There is no such thing as a 'null' value. undef is a
scalar value which that means 'not defined'.

Again, the code as written CANNOT return undef. It can only return a
list of three values. undef is a single scalar value.
The code below produces this:
$ perl test
defined(@array) is deprecated at test line 14.
(Maybe you should just omit the defined()?)
the return from jack() is 0, 3.14159, Lemmings, all of them!
$

but if I remove the 'defined' and change jack to return an 'undef', I
get this:

please don't tell us in English - tell us in Perl. I don't understand
exactly what code change you've claimed to make.
////////////////////////////////////////////////////////////
use strict;
use warnings;

sub jack{
my $int1 = 0;
my $float1 = 3.14159;
my $string = "Lemmings, all of them!";
($int1, $float1, $string);
};

my $num;
my $flt;
my $str;
if( defined(($num, $flt, $str) = jack)){
print "the return from jack() is $num, $flt, $str \n";
}
else{
print "return was undef";
}
////////////////////////////////////////////////////////////

Once more, jack CANNOT return undef. Therefore, you need to clarify
what test you're trying to create here. Are you testing to see if all
three values are undefined? Are you testing to see if at least one of
the values is undefined? At least one is defined? All are defined?

Your central problem is that the defined function takes only one
argument. If you want to test each element's defined'ness, you need to
test each one:

if (grep {defined} (($num, $flt, $str) = jack)){
print "At least one element is defined\n";
} else {
print "All elements are undefined\n";
}

if (grep {!defined} (($num, $flt, $str) = jack)){
print "At least one element is undefined\n";
} else {
print "All elements are defined\n";
}


If I've misunderstood your problem, please re-post with actual code and
a more carefully worded question.

Hope this helps,
Paul Lalli
 
A

Arndt Jonasson

I am confused about how I can detect if the function jack has returned
an UNDEFined value;

note that I don't want to catch the return from 'jack' in a single
variable @array, rather I want it to return the seperate values, as
indicated.

Is there a way to detect if 'jack' returns undef (or null or
whatever), without first catching it in an @array variable.

The code below produces this:
$ perl test
defined(@array) is deprecated at test line 14.
(Maybe you should just omit the defined()?)
the return from jack() is 0, 3.14159, Lemmings, all of them!
$

but if I remove the 'defined' and change jack to return an 'undef', I
get this:
$ perl test
Useless use of private variable in void context at test line 8.
Useless use of private variable in void context at test line 8.
Useless use of private variable in void context at test line 8.
Use of uninitialized value in concatenation (.) or string at test line
16.
Use of uninitialized value in concatenation (.) or string at test line
16.
Use of uninitialized value in concatenation (.) or string at test line
16.
the return from jack() is , ,
$


////////////////////////////////////////////////////////////
use strict;
use warnings;

sub jack{
my $int1 = 0;
my $float1 = 3.14159;
my $string = "Lemmings, all of them!";
($int1, $float1, $string);
};

my $num;
my $flt;
my $str;
if( defined(($num, $flt, $str) = jack)){
print "the return from jack() is $num, $flt, $str \n";
}
else{
print "return was undef";
}
////////////////////////////////////////////////////////////


It seems to me you want the function 'jack' to have a success and
a failure case: when successful it returns a list of three elements,
and when failing it returns 'undef'.

'undef' doesn't appear to me to be a very good value to return as
a failure indicator from a function that otherwise returns a list,
since if you call it like this

my @list = jack();

and it fails, @list will not get the value 'undef' or become !defined;
it will contain one element, which is 'undef'.

It's probably better to return an empty list. Then you can use the
test
if (@list)
to see whether the call succeeded. "if (defined @list)" will not
do anything useful.

If you call 'jack' like this

($v1, $v2, $v3) = jack();

and you are sure that the three values are all something other than
'undef' if the call succeeds, you can test any one of them:

if (defined $v1)

to see whether the call succeeded.


In a more general case, where the function 'jack' might return a list
of any length, including zero, _or_ fail, I suggest returning a
reference to a list when succeeding, and 'undef' when failing. Maybe
someone has a better recommendation; I'm fairly new to Perl myself.
 
T

Tad McClellan

Jack said:
Subject: newbie-ish question


Please put the subject of your article in the Subject of your article.

Your article is not about newbie-ish questions.

Have you seen the Posting Guidelines that are posted here frequently?

I am confused about how I can detect if the function jack has returned
an UNDEFined value;


You use the defined() function to test for undef values (but you
appear to already know that).

note that I don't want to catch the return from 'jack' in a single
variable @array, rather I want it to return the seperate values, as
indicated.


You are calling jack() in list context.

Sometimes it returns a 3-element list and sometimes it returns
a 1-element list (where the value of the 1 element is undef),
both of those are "true" when used in a list assignement, so
they can not be used to distinguish between the two cases.

It _should_ be returning either a 3-element list or
a 0-element list (the empty list) instead.

Is there a way to detect if 'jack' returns undef (or null or
whatever), without first catching it in an @array variable.

but if I remove the 'defined' and change jack to return an 'undef', I
get this:


Try changing jack() to return the empty list instead of a 1-element list.

Then you can use the value of the list-assignment to detect a
populated list vs. the empty list:


-------------------------
#!/usr/bin/perl
use warnings;
use strict;

sub jack{
my $int1 = 0;
my $float1 = 3.14159;
my $string = "Lemmings, all of them!";
# return($int1, $float1, $string);
return ();
};

if( my($num, $flt, $str) = jack){
print "the return from jack() is $num, $flt, $str \n";
}
else{
print "return was the empty list\n";
}
-------------------------


The way you had it, $int1 is undef because that is what was in
the list returned from jack().

$flt and $str are also undef, but for a different reason
(because the RHS of a list assignment was "too short").
 
A

Anno Siegel

Arndt Jonasson said:
It seems to me you want the function 'jack' to have a success and
a failure case: when successful it returns a list of three elements,
and when failing it returns 'undef'.

'undef' doesn't appear to me to be a very good value to return as
a failure indicator from a function that otherwise returns a list,
since if you call it like this

my @list = jack();

and it fails, @list will not get the value 'undef' or become !defined;
it will contain one element, which is 'undef'.

It's probably better to return an empty list. Then you can use the
test
if (@list)
to see whether the call succeeded. "if (defined @list)" will not
do anything useful.

If you call 'jack' like this

($v1, $v2, $v3) = jack();

and you are sure that the three values are all something other than
'undef' if the call succeeds, you can test any one of them:

if (defined $v1)

to see whether the call succeeded.

There is a better way:

if ( $v1, $v2, $v3) = jack() ) {
# regular case, jack() has returned at least one scalar
# do something with $v1, $v2, $v2
} else {
# failure, jack() has returned nothing
}
In a more general case, where the function 'jack' might return a list
of any length, including zero, _or_ fail, I suggest returning a
reference to a list when succeeding, and 'undef' when failing. Maybe
someone has a better recommendation; I'm fairly new to Perl myself.

The question with arbitrary lists is whether an empty list is a
possible return value. If it isn't, the same method can be used.
If it is, returning a reference on success and nothing on failure
is a common way to resolve this.

Anno
 
A

Anno Siegel

Arndt Jonasson said:
It seems to me you want the function 'jack' to have a success and
a failure case: when successful it returns a list of three elements,
and when failing it returns 'undef'.

'undef' doesn't appear to me to be a very good value to return as
a failure indicator from a function that otherwise returns a list,
since if you call it like this

my @list = jack();

and it fails, @list will not get the value 'undef' or become !defined;
it will contain one element, which is 'undef'.

It's probably better to return an empty list. Then you can use the
test
if (@list)
to see whether the call succeeded. "if (defined @list)" will not
do anything useful.

If you call 'jack' like this

($v1, $v2, $v3) = jack();

and you are sure that the three values are all something other than
'undef' if the call succeeds, you can test any one of them:

if (defined $v1)

to see whether the call succeeded.

There is a better way:

if ( my ( $v1, $v2, $v3) = jack() ) {
# regular case, jack() has returned at least one scalar
# do something with $v1, $v2, $v2
} else {
# failure, jack() has returned nothing
}
In a more general case, where the function 'jack' might return a list
of any length, including zero, _or_ fail, I suggest returning a
reference to a list when succeeding, and 'undef' when failing. Maybe
someone has a better recommendation; I'm fairly new to Perl myself.

The question with arbitrary lists is whether an empty list is a
possible return value. If it isn't, the same method can be used.
If it is, returning a reference on success and nothing on failure
is a common way to resolve this.

Anno
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top