Thread

Posted on Wed Jan 18 01:42:54 2006 by je44ery
:Restricted methods imported into child classes?
Is there anyway to export :Restricted methods from parent classes and import then into child classes? I have a few such methods in child classes that could be refactored back up a level or two in the heirarchy. However, I don't want to call them like:
ParentClass::_restricted_sub(param1);
I would prefer just:
_restricted_sub(param1);
In case I move the sub further up the class heirarchy again. Is there any way to solve this problem, or is perhaps my approach incorrect?
Direct Responses: 1637 | Write a response
Posted on Wed Jan 18 17:54:52 2006 by jdhedden in response to 1632
Re: :Restricted methods imported into child classes?
What you are describing is functions; not methods. Both are implemented as subroutines. Functions are invoked with just their name:
do_function($some_arg);
Methods are invoked via an object:
$obj->my_method($arg);
Methods are inherited, so you don't have to do anything extra to access a parent class's methods from a child class's objects.

To access functions outside of a class, you must either use a fully-qualified function name:
Parent::Class::some_function($an_arg);
Or you can use the Exporter module to export a function name into another class's namespace. Do 'perldoc Exporter' for how to do this.

Finally, ':Restricted' and ':Private' only work on method; not functions.
Direct Responses: 1638 | 1639 | Write a response
Posted on Wed Jan 18 18:59:46 2006 by je44ery in response to 1637
Re: :Restricted methods imported into child classes?
Not sure if I'm misunderstanding, but I'm pretty sure that :Restricted and :Private *do* work on functions. I'm not sure if you intended this, but it works, and I like it that way. If you take away that functionality because it is not architecturally correct, then please let me know.

These 3 source files:
$ cat PPP.pm package PPP; use Object::InsideOut; sub _thisone : Private { print "This works!\n"; } 1; $ cat CCC.pm package CCC; use Object::InsideOut qw(PPP); sub pubby { PPP::_thisone(); } 1; $ cat test_inherit.pl #!/usr/bin/perl -w use warnings; use strict; package main; use CCC; my $obj = CCC->new(); $obj->pubby();

Give me this result:
# ./test_inherit.pl OIO::Method error: Can't call private method 'PPP->_thisone' from class 'CCC' Package: CCC File: CCC.pm Line: 5 Trace begun at CCC.pm line 5 CCC::pubby('CCC=SCALAR(0x3024f290)') called at test_inherit.pl line 13
Write a response
Posted on Wed Jan 18 19:25:25 2006 by je44ery in response to 1637
Re: :Restricted methods imported into child classes?
Thanks. I already know about Exporter. The problem lies in how to use it. To import these functions, I'd have to do this:
package ChildClass; use ParentClass qw(&_func);

But to use Object::InsideOut properly, I should be doing this:
package ChildClass; use Object::InsideOut qw(ParentClass);

So the two uses conflict with each other. This has made me question my design a bit. It doesn't *seem* wrong to want these private/restricted functions to be available in child classes without fully qualifying the name space. However, I'm not as versed in Perl OO (or general OO) as yourself. I'm not asking for a Perl OO tutorial, but if you could tell me whether my approach is all wrong or not would be appreciated.

This module has been a lifesaver for me. Thanks for all the work.
Direct Responses: 1640 | Write a response
Posted on Wed Jan 18 20:38:37 2006 by jdhedden in response to 1639
Re: :Restricted methods imported into child classes?
There is no conflict. The syntax you want is in the docs:
If a parent class takes parameters, enclose them in an array ref (mandatory) following the name of the parent class: package My::Project { use Object::InsideOut 'My::Class' => [ 'param1', 'param2' ], 'Another::Class' => [ 'param' ]; ... }
In your case, you would use:
package ChildClass; { use Object::InsideOut 'ParentClass' => [ '_func' ]; ... }
Direct Responses: 1642 | 1643 | Write a response
Posted on Wed Jan 18 21:23:58 2006 by je44ery in response to 1640
Re: :Restricted methods imported into child classes?
Ah-ha! Thank you very much. I had seen that syntax in your InsideOut docs, but I didn't connect it as being useful to my problem. Now it is obvious, tho.
Write a response
Posted on Wed Jan 18 22:18:02 2006 by je44ery in response to 1640
Re: :Restricted methods imported into child classes?
I think that I hit another seeming snag. My version of Exporter doesn't allow this syntax in parent modules / classes:
package YourModule; use Exporter 'import'; # gives you Exporter's import() method directly @EXPORT_OK = qw(munge frobnicate); # symbols to export on request

Therefore, I must use the other syntax, which is:
package YourModule; require Exporter; @ISA = qw(Exporter); @EXPORT_OK = qw(munge frobnicate); # symbols to export on request

But the Object::InsideOut docs say this:
"Object::InsideOut acts as a replacement for the base pragma: It loads the parent module(s), calls their import functions, and sets up the sub-class's @ISA array. Therefore, you must not use base ... yourself, or try to set up @ISA arrays."

What to do now?
Direct Responses: 1652 | Write a response
Posted on Thu Jan 19 06:36:11 2006 by jdhedden in response to 1643
Re: :Restricted methods imported into child classes?
Turns out there was a problem dealing with Exporter. I uploaded v1.33 which fixes this. Here's an example:
use strict; use warnings; package Foo; { use Object::InsideOut 'Exporter'; BEGIN { our @EXPORT_OK = qw(foo_name); } sub foo_name { return (__PACKAGE__); } } package Bar; { use Object::InsideOut 'Foo' => [ qw(foo_name) ]; sub get_foo_name { return (foo_name()); } } package main; print("Bar got Foo's name as '", Bar::get_foo_name(), "'\n");
Note the use of the BEGIN block to ensure the @EXPORT_OK array gets populated properly.
Direct Responses: 1698 | Write a response
Posted on Tue Jan 24 23:29:27 2006 by je44ery in response to 1652
Re: :Restricted methods imported into child classes?
I now have this working swimmingly. I am using it for the 'Type' subroutines in the %init_args hash mostly.
$ cat Top.pm package Top; use Object::InsideOut 'Exporter'; BEGIN { our @EXPORT_OK = qw(_check_foo); } sub _foo : Restricted { return 1; } 1;
$ cat Top/Middle.pm package Top::Middle; use Object::InsideOut 'Exporter', 'Top' => [ qw(_check_foo) ],; BEGIN { our @EXPORT_OK = qw(_check_foo); } my @info :Field('Standard' => 'info'); my %init_args :InitArgs = ( 'INFO' => { 'Type' => \&_check_foo, 'Field' => \@info, }, ); 1;
$ cat test_export.pl #!/usr/bin/perl -w use strict; use warnings; use Top::Middle; my $obj = Top::Middle->new( 'info' => 'some_data_or_whatever' ); exit 0;
Write a response