Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

modifying perl functions without having to write own functions...

by argv (Pilgrim)
on Dec 23, 2006 at 18:06 UTC ( [id://591466]=perlquestion: print w/replies, xml ) Need Help??

argv has asked for the wisdom of the Perl Monks concerning the following question:

I've found there are more cases where I'd like chomp to return something other than "the number of bytes chomped off the end" of EXPR. Of course, making any changes to existing documented behavior would require incompatibilities, but I was wondering if there are ways to *efficiently* introduce extensions to existing behavior without having to change the actual source code. That is, I don't want to have to write a new function that does the modified behavior since it wouldn't be "more efficient" than just writing the mod in-place.

My example is below, where I coerce chomp to return the EXPR it acted upon:

open FILE, "list-of-emails-one-per-line.txt"; @emails{(array) chomp <FILE>} = (); # %emails is now a hash where each + key is an email address close FILE;

So, I'd like to add this "coercing" behavior without having to write a new special-case chomp function. A similar thing would be to extend "lc" (et al.) to act on an array as well as a string.

Is this possible, or am I stuck writing my own functions? UPDATE: Please don't tell me how to solve the specific task illustrated in the example (such as using "chomp (@_ = <FILE>), @_" to simply yield the desired list. That isn't answering the question on whether "extensions" to existing functions are possible.

Replies are listed 'Best First'.
Re: modifying perl functions without having to write own functions...
by ikegami (Patriarch) on Dec 23, 2006 at 18:19 UTC
    No. The functions wern't written that way, so they won't do that. However, it's often trivial to make the builtins work on arrays using map and apply.

    Examples using a function that returns the transformed value:

    @new = map lc, @old; @new = map ord, @old; @new = map { sprintf('%02X', $_) } @old;

    Examples using a function that transforms the value in-place:

    use List::MoreUtils qw( apply ); @new = apply { chomp; } @old; @new = apply { tr/a-z/n-za-m/; } @old;

    It's particularly easy when the the function uses $_ when no argument is supplied. You can make your own functions work on $_ by using the following pattern:

    sub func { for (my $s = @_ ? $_[0] : $_) { ... do something with $_ ... return $_; } } $new = func($old); @new = map func, @old;
Re: modifying perl functions without having to write own functions...
by dirving (Friar) on Dec 23, 2006 at 19:21 UTC
    In general, it's probably a really bad idea to do this. Another programmer coming along reading your code (or you a few months down the line) expect the built-ins to do what they're documented to do. If they see something like:
    my $chomped = chomp (@array)
    They will expect $chomped to contain the number of elements chomped as documented, not the first element of the array post-chomping. So unless you want to maintain a list of all the built-ins you've over-ridden at the top of your code and have any future programmers working on the code referring back to it constantly, you're better off just writing your own function. The two examples you give are trivially written as
    sub chomp_and_return { chomp @_; return @_; } sub lc_array { map { lc } @_; }
    which are just as easy to use as the built-ins, but give different names to different behavior and are consequently much more obvious to the reader.

    If after reading and considering this post you still want to over-ride the built-ins with different behavior, see the "Overriding Built-in Functions" heading of perlsub.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://591466]
Approved by Joost
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (6)
As of 2024-04-23 21:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found