> All functions in the module can be used as method; the trick 
> used to do
> it is to use the __PACKAGE__ "variable" the following way:
> 
> sub init {
>   my $class = shift if (@_ and $_[0] eq __PACKAGE__);
>   my (%options) = @_;
> ...
> }
> 
> # or : 
> 
> sub bindRegexp
> {
>   my $self = ref($_[0]) eq __PACKAGE__  ? shift : $globalIvy;
>   my ($regexp, $cb) = @_;
> ...
> }
> 
> 
> The problem appears now, when using construction such as :
> 
> use Net::Ivy; 
> Net::Ivy->init(-appName => "foo", -loopMode => "local");
> # is fine!
> 
> #but when using the old construction with the wrapper:
> use Ivy; 
> Ivy->init(-appName => "foo", -loopMode => "local");
> 
> Error in Net::Ivy::init: option -appName is mandatory
>  at -e line 1
> 
> # because now, ref($_[0]) eq __PACKAGE__ is false
> 
> 
> Do you have suggestions? (I could find a correction, but not sure it
> will be really a good one).

Well, to be honest this is a dirty trick IMO, that can cause subtle
problems.  Better to go the route that File::Spec went, and add a function
wrapper for the methods. (File::Spec::Functions autogenerates the functional
equivelents from the methods on demand).

However, this would just add more modification requirements to your code.
Assuming that the first arg to your functions is NEVER a descendent of
Net::Ivy (or Ivy whichever is your root class) when called in functional
form then the following should work ok:

sub init {
   my $class = shift if (@_ and UNIVERSAL::isa($_[0],__PACKAGE__));
   my (%options) = @_;
   ...
}
sub bindRegexp
{
  my $self = UNIVERSAL::isa($_[0],__PACKAGE__)  ? shift : $globalIvy;
  my ($regexp, $cb) = @_;
  ...
}

Cheers,
Yves


Reply via email to