Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • The so called import-on-demand feature of Java:

    import foo.bar.*;
    is generally considered bad practice, good only at quick-and-dirty code. Tools like Eclipse help expand these evil statements into qualified imports after compiling and resolving the class names in the current source file.

    Some of the problems are mentioned at http://javadude.com/tools/importifier/ [javadude.com]

    • If you use a name that exists in more than one package, the Java compiler cannot determine which fully-qualified name to use. You need to specify the full qualification yourself.
    • If a name is currently unambiguous (exists in only one package that you specify via import-on-demand), someone could add the same name to another package and your program will no longer compile.
    • If someone is reading your code, they need to check in each specified package to see which contains a referenced class Foo.

    For Perl, at least the last problem remains the same: where that Foo came from? Add two or three such statements "aliased 'Foo::*';" and "aliased 'Bar::*';" and the actual (qualified) dependencies are hidden from a cursory glance at the code. Obviously, it may occasionally look right and clever for the ones used to the magical powers of AUTOLOAD or even subtler things. On the long run, we can regret that cleverness, as Damian says on PBP.

    On the other hand, almost the same rate of elegance and conciseness can be obtained with a little change in the object architecture, leading to code like this:

    use Our::Code;

    my $god = Our::Code->new;
    my $cust       = $god->new_customer;
    my $datacenter = $god->new_datacenter;
    my $item       = $god->new_item;
    my $office     = $god->new_office;
    my $order      = $god->new_order;
    my $server     = $god->new_server;
    my $ded_server = $god->new_dedicated_server;   # unsure of this
    The cleverness moves from the user's code into the library (which can rely on magical powers to load modules and do the right thing appear to the user). You can tell "but now I have to change my library code?" Yep. With a bunch of related classes and no code to integrate them, that seems like a good idea.

    For example, that's what I actually did at the Business-BR-Ids distribution which implements code for testing various Brazilian id numbers. Instead of saying:

    use Business::BR::CPF qw(test_cpf); # natural person's id
    use Business::BR::CNPJ qw(test_cnpj); # company'is id
    use Business::BR::CPF qw(test_pis); # natural person's health id

    test_cpf($cpf);
    test_cnpj($cnpj);
    test_pis($pis);
    I use

    use Business::BR::Ids qw(test_id);

    test_id('cpf', $cpf);
    test_id('cnpj', $cnpj);
    test_id('pis', $pis);
    and let Business::BR::Ids load Business::BR::* modules when necessary and with appropriate error messages in the case of failure.
    • You know, I think you make a compelling argument. I'll have to consider this and I might just drop the idea.

      • It used to be pretty standard in Python to import the whole shebang as well (ie from foo import *) but that is frowned upon today as well. Mainly because of namespace pollution.

        You really should only call what you need and if you do somthing like Our::Code::*; You may be surprised by what you are importing (whether you did it intentionally or not).