in reply to Re: Moose: Accessing subroutines in packages used by Moose class
in thread Moose: Accessing subroutines in packages used by Moose class

I think that Moose won't write the code that handles delegating to a function (by shifting $_[0] away). But other than that, letting Moose handle the delegation is certainly a much better approach than handling the delegation yourself (once you've bought into Moose).

  • Comment on Re^2: Moose: Accessing subroutines in packages used by Moose class
  • Download Code

Replies are listed 'Best First'.
Re^3: Moose: Accessing subroutines in packages used by Moose class
by Arunbear (Prior) on Apr 18, 2016 at 12:22 UTC
    D'oh! You're quite correct, though it can be fixed with additional hackery:
    package Bogus; use Data::Dump 'pp'; sub foo { printf "foo got %s\n", pp([@_]) } sub bar { printf "bar got %s\n", pp([@_]) } sub baz { printf "baz got %s\n", pp([@_]) } package MyBogus; use Moose; use MooseX::NonMoose; extends 'Bogus'; around [qw( foo bar baz )] => sub { my $orig = shift; my $self = shift; $orig->(@_); }; package Tester; use Moose; use MyBogus; has 'bogus' => ( is => 'bare', default => sub { MyBogus->new }, handles => [qw( foo bar baz )], ); package main; my $tester = Tester->new; $tester->bar('bar'); $tester->foo('ram'); $tester->baz('ewe'); __END__ prints: bar got ["bar"] foo got ["ram"] baz got ["ewe"]

      Oooh - I like that use of around for wrapping functions. In my mind, I didn't make the connections between functions and methods and thought of manually writing the wrapper functions, but around already provides all functionality that is needed, at the price of another class/package shoved in between the use and the importing of the code.

      Sorry, I'm pretty new to Moose and I'm not clear as to whether this applies to my situation where my Moose class is using the subroutines pulled in from a non-Moose module.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        Yes, it applies to your situation. I couldn't install X11::GUITest, so I created a dummy package to illustrate the technique.

        The package 'Bogus' in my example is analogous to X11::GUITest in your example i.e. it contains the subs that you want to wrap.

        So translating to your example it would look like:
        package X11_GUITest_Wrapper; use Moose; use MooseX::NonMoose; extends 'X11::GUITest'; around [qw( SendKeys FindWindowLike ClickWindow SetEventSendDelay )] = +> sub { my $orig = shift; my $self = shift; $orig->(@_); }; 1;
        Then to use it:
        package FFMech; $ENV{'DISPLAY'} = ':0.0'; use Moose; use Modern::Perl; use MooseX::NonMoose; extends 'WWW::Mechanize::Firefox'; has 'x11_guitest_wrapper' => ( is => 'bare', default => sub { X11_GUITest_Wrapper->new }, handles => [qw( SendKeys FindWindowLike ClickWindow SetEventSendDe +lay )], ); # ... 1;

        I think you should be able to adapt this to your needs by rewriting the package Bogus as follows:

        package Bogus; use strict; use X11::GUITest qw(SendKeys); # and whatever other functions

        (and maybe also renaming it away from Bogus to, say, Class::X11::GUITest), and then using that from the package MyBogus:

        package MyBogus; use Moose; use MooseX::NonMoose; extends 'Bogus'; around ...;

        In theory, you should even be able to do away with the intermediate Class::X11::GUITest class by using the following:

        package X11::GUITest::Moosified; use Moose; use MooseX::NonMoose; extends 'X11::GUITest'; around ['SendKeys'] => sub { ... };