in reply to Re^3: Questions about sharing code
in thread Questions about sharing code

I still boggle at this idea. Much better would be:

use Scalar::Util qw( weaken ); # ... weaken( $some_ref );

For one, it abstracts the idea of weaken() so that you can easily replace it with a wrapper if you later need to wrap Scalar::Util::weaken() or use a weaken() from a different module (which improves the maintainability of your code). It makes the code easier to "parse by translating the shapes that form characters" instead of having to repeatedly be distracted by "parsing by translating the shapes that form characters" these long names, you can just "parse by translating the shapes that form characters" the perfectly descriptive "weaken" name; like using "read"/"reading" in place of the long quoted phrases above. It makes it easier to tell why Scalar::Util is being used. It confirms at compile time that the desired function is actually provided by the module and is not just meant for internal use or use as a method (something that isn't even clear to the person reading the code as you wrote it). It means that mistyping the subroutine name doesn't accidentally call an internal routine or method from that module. It allows the module to decide to not even load functionality that is not going to be used (or other, more advanced techniques such as maintaining backward compatability more conveniently).

Module names need to be globally unique and so should be relatively long and descriptive, which is why I always try to make it so my module names only need to be mentioned once for them to be used. Repeating a magic string constant (the module name) over and over in your code does not make it easier to maintain. Do you avoid defining constants because it makes the code easier to maintain if the person reading the code can immediately see the value of the constant because the 7 is right there in front of their face? Or do you name your constants like SUNDAY_0, MONDAY_1, ... to get the best of both worlds?

Repeating the source of the function at every invocation makes about as much sense to me as naming your local subroutines "sub frob_line237" so everyone will know which line to jump to in order to find the definition of the function.

- tye        

Replies are listed 'Best First'.
Re^5: Questions about sharing code (@EXPORT_OK++)
by dragonchild (Archbishop) on Nov 28, 2007 at 17:42 UTC
    And all of those reasons are great reasons. The reason I do it for all my OO CPAN modules (and most of mine are OO) is that I don't want $obj->weaken() to be a possibility. Particularly if weaken() is a method in my base class.

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?

      There are more problems than that. This is why I usually write classes with separate packages for class methods, object methods, and utility functionsmethods. Unfortunately, caller and thus SUPER: and its ilk are still too stupid to deal with code that actually prevents such method confusion:

      package My::Class::_implement; use Scalar::Util qw( weaken ); sub My::Class::new { # ... } sub My::Class::Object::method { # ... weaken( $someRef ); # ... }

      Yes, you can abstract out having to re-type class names fairly easily; this is just a quick example.

      - tye        

Re^5: Questions about sharing code (@EXPORT_OK++)
by bradcathey (Prior) on Nov 28, 2007 at 17:48 UTC

    I see dragonchild's point, but I think yours, tye is "cleaner". Maybe this is retro and a bit unhackerish, but I just add a remark after calling a sub from another module:

    weaken( $some_ref ); #from Scalar::Util

    Anyway, thanks to both of ye for getting me back on the right path with @Export.


    —Brad
    "The important work of moving the world forward does not wait to be done by perfect men." George Eliot