Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are valid Perl module return values?

Tags:

module

perl

The common practice in Perl is of course to end modules with 1; so that a call to require can then be checked for success. Is there any reason that the return value couldn't be another true value? In my testing, it does not see to cause any problems, but I'd like to know if anyone has run across any issues (such as some other modules or pragmas or anything that expect the value actually to be 1 and not just true).

Edit: By popular opinion, and since it will only work once (good tip), the code example is gone. Seems the consensus is that its safe to return any true value, but never to rely on the that value in calling code since require will return 1 after the first loading

like image 768
Eric Strom Avatar asked Dec 07 '09 15:12

Eric Strom


People also ask

How do I return a Perl script?

return() function in Perl returns Value at the end of a subroutine, block, or do function. Returned value might be scalar, array, or a hash according to the selected context.

What is return in Perl?

Perl provides a return statement which can be used to exit a function, and provide a value when a function call is evaluated. In the absence of a return statement, the value of a function call will be the last expression which was evaluated in the body of the function.


2 Answers

I've been putting silly things at the end of my modules for a while. There's no harm and its a little Easter egg. uny2k helpfully ends with "Yes, this code is a joke." Class::Fields is chock full of them.

Taking it one step further, sometimes when a function is documented to return true and false I will return something other than 1 for true. This is to punish people who write if foo() == 1 when they mean if foo(). This was around the same period I was writing use constant TRUE => 1==1; use constant FALSE => !TRUE;

I have seen the return value of a module used in production code. I don't recall exactly why. The developer's logic was... tortured. I believe it was something along the lines of not wanting to have to write just one line instead of two. I don't remember why he didn't just export it.

This was the same developer who used %_ to pass arguments around (the *_ symbol is global across packages) and wrote 150 line map statements inside map statements.

The danger of using the return value, aside from obfuscation, is that it only works once.

$ cat Foo.pm
package Foo;

return "Basset hounds got long ears";

$ cat test.plx
#!/usr/bin/perl -w

print require Foo, "\n";
print require Foo, "\n";

$ perl -I. test.plx
Basset hounds got long ears
1

The first call to require evaluates Foo.pm and returns the return value. The second call sees its already in %INC and just returns true. And you can't even be sure that you're the first thing to require the code. You can get around this with do "Foo.pm" but now you're reloading the module each time with warnings about redefined routines, problems for performance and possibly reinitializing globals. Its not worth it.

like image 179
Schwern Avatar answered Oct 19 '22 05:10

Schwern


I think (1) there's no problem with returning any arbitrary true value from your module but (2) there's a big problem with the obscure, overly-clever code you suggest to exploit the module implementation details. Don't do that.

like image 34
Jonathan Feinberg Avatar answered Oct 19 '22 04:10

Jonathan Feinberg