tags:

views:

251

answers:

6

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

+8  A: 

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.

Jonathan Feinberg
+4  A: 

The purpose is that if your module returns false, the require can fail at that point. Nobody cares about or relies on the value beyond it being true or false.

You should follow suit. You are making it so that your modules depend on the actual value beyond whether it is true or false. In the example you gave, for instance, if your require happens to return 1, the require will succeed, but your clever constructor will fail.

Adam Bellaire
+6  A: 

Anything is a valid return value. If you want the require to succeed, it needs to be a true value. If you don't want the require to succeed (e.g. unsupported platform, missing library), use a false value.

To see what other people have used as return values, check out Acme::ReturnValue.

People don't expect to use the return value for anything, so I wouldn't confuse people by trying to do that, no matter how clever it seems at the time. :)

brian d foy
Hey brian! You're a SO god.
Jonathan Feinberg
Meant to say hi the other day, but I was lazy. Looks like you are doing well. :)
brian d foy
+3  A: 

Mark Dominus, author of Higher-Order Perl, explains my favorite:

I have very rarely used $flag = 'Cogito ergo sum'; which as everyone knows is self-evidently true in all possible universes. This ensures maximum portability.

Greg Bacon
+1  A: 

One thing that you'll run into with require is that it only returns the module's return value the first time that the module is loaded. If the module was already loaded, require returns 1 without loading the module again.

The do file statement will reload the file each time, and returns the file's return value each time. I've used it to store configuration data in a file in the form of an anonymous hash.

Kenster
`do file` "works", but it's really hard to perform error checking. You'd be much better off storing config data in a defined parsable format like YAML, rather than directly populating data structures in a separate library.
Ether
@Ether I can think of reasons not to stick config info into a Perl data structure (its insecure and unportable) but error checking isn't one of them. Perl does the checking for you. `do $file || die` is sufficient.
Schwern
+4  A: 

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.

Schwern