When writing a Perl module, do I need to specifically test an object instance in all my methods?

I am writing a module that has several methods. Consider this:

package MyPackage; sub new { ... } sub do_your_job { ... } 1; 

What does it mean for someone to call do_your_job as MyPackage->do_your_job instead of $obj->do_your_job ? Do I need to check every method in which I get the link as the first argument?

+4
source share
6 answers

Not. If your module has only the most minimal documentation, then it should be clear that do_your_job is the method to call for the object. If someone wants to call it some other way, this is his mistake.

Of course, you can check if the first parameter for your method is a blessed object. But this has at least two drawbacks: you lose a little performance, and you clutter up your methods with code that really doesn't do anything promised by the method name.

+9
source

No, you do not need to check; you can simply document that it is an object method and trustees to use it as such. But if you feel that it is not enough, you can certainly check.

The same applies to arguments other than the implicit object / class argument of the invocation method. You can have a parameter, which should be a ref array, or a positive integer less than 10, or an object of a certain type, or something else. One way is to get subscribers to follow the documentation; the other is to believe nothing.

+5
source

The short answers in theory are "Nothing" and "This is not a bad idea."

However, in practice, documentation can solve these problems. There is a general courtesy in the Perl community that instructs developers to use modules only as they have been documented.

Perl modules do not guarantee that internal elements will never change. Thus, the implied convention is that developers will not dig inside the module / class if they do not implement this module / class.

+5
source

As others have said, document what your module does and trust the user. However, it is worth considering the philosophical difference between a class call and an object call. If your Perl module provides a way to create objects, many of the methods in this class can rely on data specific to an individual object. This is probably the most common way to call methods: as soon as you have an object, you simply do $object->method(…) . However, it is likely that some methods of the class are common and do not need data from a specific object. They are often called using the package name, and this is most often encountered when calling the new() method, for example LWP::UserAgent->new() .

Conveniently, Perl allows you to treat these two cases the same way, using something like my $self = shift; at the beginning of the method: if the method is called on the object, $self gets the value of the reference to the object, if called in the class, $self gets the name of the package.

Even if the method is called in the class, so $self contains the name of the package, you can still call other methods in this package in the same way by doing $self->method(…) . Then this is compatible with calling the original method on a specific object, so everything sticks together.

As one example, the Perl Math :: BigInt package includes quite a few methods, some of which are designed to be called on the package (class) itself (for example, new() ), some of which must be called on separate objects (for example, round() ), and some on any (e.g. accuracy() ).

Moral: it must be consistent with the functionality of the method as to whether it is capable of a reasonable meaning. It is reasonable to assume that any method is invoked with the expectation that it will do what you advertise. However, it is not required that the method call be on the object when it makes sense to call this method on the class itself.

+3
source

You do not need to check the referent of the method call. However, based on the needs of a particular application, you can:

  sub some_method { my( $class ) = @_; croak( "This is a class method only" ) if ref $class; ... } 

Although I'm not so interested, you can verify that you have an instance before trying to dereference something:

  sub some_instance_method { my( $self ) = @_; croak( "This is an instance method only" ) unless ref $self; $self->{some_attr}; } 

I am inclined to suggest that a higher level will call it, as I documented it.

+3
source

Use Moose and forget about plumbing.

-3
source

All Articles