Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

override CORE sub and keep method in same package

by bulk88 (Priest)
on Oct 14, 2013 at 20:20 UTC ( #1058207=perlquestion: print w/ replies, xml ) Need Help??
bulk88 has asked for the wisdom of the Perl Monks concerning the following question:

I currently have a perl module I am modifying. I am trying to hook the select builtin and define my own in pure perl. The module has a method called select that looks like this
sub select { shift if defined $_[0] && !ref($_[0]); my($r,$w,$e,$t) = @_; my @result = (); my $rb = defined $r ? $r->[VEC_BITS] : undef; my $wb = defined $w ? $w->[VEC_BITS] : undef; my $eb = defined $e ? $e->[VEC_BITS] : undef; if(select($rb,$wb,$eb,$t) > 0) ################################################ }
I tried to override the builtin select with use subs 'select'; and then defining a 2nd select sub in the same package. I get a "Deep recursion on subroutine "IO::Select::Foo::select"" now (my custom select sub is overridden by the select method sub). How do I override the builtin select package wide and still keep my select method sub (which is public API and cant be renamed)?

Comment on override CORE sub and keep method in same package
Select or Download Code
Re: override CORE sub and keep method in same package
by BrowserUk (Pope) on Oct 14, 2013 at 20:53 UTC

    Have you seen/tried Overriding-Built-in-Functions?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Yes. "CORE::GLOBAL::" is too aggressive. It is process wide supposedly.

        Update: I assuming from your typically terse description that you goal is to override the function of the built-in select only within the IO::Select module without overriding the select method it presents to its callers.

        If that is not the case, perhaps you could clarify your requirements?

        Yes. "CORE::GLOBAL::" is too aggressive.

        Hm. The CORE::GLOBAL discussion is only a one part of the discussion referenced.

        There is also use REGlob 'glob';            # override glob() in Foo:: only, amongst others.

        But, to answer your specific problem, I'd suggest adding:

        sub yourSelect { ... } sub select { local *CORE::GLOBAL::select = *yourSelect; shift if defined $_[0] && !ref($_[0]); my($r,$w,$e,$t) = @_; my @result = (); my $rb = defined $r ? $r->[VEC_BITS] : undef; my $wb = defined $w ? $w->[VEC_BITS] : undef; my $eb = defined $e ? $e->[VEC_BITS] : undef; if(select($rb,$wb,$eb,$t) > 0) ################################################ }

        Wherever select is used in IO::Select. Make it conditional if appropriate.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: override CORE sub and keep method in same package
by LanX (Canon) on Oct 14, 2013 at 21:16 UTC
    A method is just a sub in the class' package. So importing an overridden sub must conflict with a method of same name.

    But I don't really understand your intention (or better mistrust the idea)

    If you want to make sure that the original built-in is called use CORE::select, if you need a different select better name it select2 or new::select and change the source accordingly.

    update

    the only way I can think of is to delete all subs with name select and to use AUTOLOAD to try to distinguish if its called as a method or a built-in (the first argument is blessed)

    update

    AUTOLOAD is even not necessary, write your own select to check the caller and switch accordingly.

    If it's called within the package/module delegate to your pseudo-built-in otherwise call the method.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

Re: override CORE sub and keep method in same package (another package)
by tye (Cardinal) on Oct 15, 2013 at 02:56 UTC
    package Your::Class::_internal; use Custom::Select 'select'; # Replaces CORE select() sub Your::Class::select { ... select( ... ) ... }

    - tye        

Re: override CORE sub and keep method in same package
by tobyink (Abbot) on Oct 15, 2013 at 07:47 UTC

    Within your custom select function you are trying to call the "real" select function. However, you are actually recursively calling your own custom select function. Prefix the call to the "real" select function with CORE:: to prevent this recursion.

    use subs 'select'; sub select { my ($fh) = @_; warn "inside my custom select\n"; CORE::select $fh; } select STDERR; print "Hello to STDERR!\n"; select STDOUT;

    Update: Meh; I see now that you want to do the above, but also provide another sub called select which is what will be available to outside code. This can be done with a little namespace::clean magic...

    use v5.12; use warnings; package MyModule; # This is the override for the select built-in. # use subs 'select'; sub select { my ($fh) = @_; warn "inside my custom select\n"; CORE::select($fh); } # Here's the select function we're going to expose to outside # code. # require namespace::clean; namespace::clean->clean_subroutines(__PACKAGE__, 'select'); no strict 'refs'; *{'select'} = sub { # Note that we can use the select override even within # this sub!! select *STDERR; print "Hello to STDERR!\n"; select *STDOUT; }; 1;
    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1058207]
Front-paged by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (9)
As of 2014-09-18 07:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (108 votes), past polls