What you are actually asking
Quoting man perldata
:
When you use the use warnings
pragma or Perl's -w command-line option, you may see warnings about useless uses of constants or functions in "void context". Void context just means the value has been discarded, such as a statement containing only "fred";
or getpwuid(0);
. It still counts as scalar context for functions that care whether or not they're being called in list context.
User-defined subroutines may choose to care whether they are being called in a void, scalar, or list context. Most subroutines do not need to bother, though. That's because both scalars and lists are automatically interpolated into lists. See wantarray for how you would dynamically discern your function's calling context.
So you’re asking if it is possible to throw value of a function call away completely if the call is performed in list or scalar context otherwise.
The answer is yes!
In scalar context, only last element of a list is used, other elements are evaluated in void context. Even more true: The “list” actually never was a list. Read more on behavior of comma operator in scalar context in man perlop for explanation. It is also explained in other words near the end of description section in man perlfunc. And finally perldoc -f scalar
mentions this too.
In list context, there is no such direct way. You need to use the same trick as above to get an arbitrary scalar (preferably 0) and then get rid of it so that it does not influence the contents of your list. Empty list repetition is what you’re looking for. (By the way repetition operator evaluates its second operand in scalar context.)
sub test_context() {
wantarray and die "list\n";
defined wantarray and die "scalar\n";
die "void\n";
}
$\ = "\n"; # to make output prettier
### Uncomment the one you want to test.
# -- Somewhat canonical examples of contexts
#[test_context]; # list (+ warning of class 'void')
#print test_context; # list
#scalar(test_context); # scalar (forces scalar context anywhere)
#my $x = test_context; # scalar
#test_context; # void
#
# -- Examples of forcing void context
# Replace test_context with a fixed scalar and try again to see that even if
# the function returned a value, it would get discarded. Ignore the 'void' warning.
#print my $x = (test_context, 42);
#print '^', () x (test_context, 0), '$';
Caveat: no void()
You cannot create a void
function, whose usage would resemble that one of scalar
.
sub void {
();
}
print void(test_context);
This would result in test
being called in list context, because function parameters are always evaluated in list context, unless told otherwise in prototype. And prototypes cannot force void context.
You can only implement such a thing by changing Perl’s syntax, which is possible but quite complicated.
The best approximation you can get with default Perl syntax is presented in ikegami’s answer.
Why would you want such a thing?
I assume this question arose from pure idle curiosity and maybe from desire to understand Perl contexts better. It has no real use whatsoever, in my opinion. As example in perldoc -f wantarray
implies, the undefined return value representing void context is intended to be used to speed up the computation, e.g. to avoid output generation if side-effects can be performed without it.
return unless defined wantarray; # don't bother doing more
my @a = complex_calculation();
return wantarray ? @a : "@a";