Useful errors for Moose and MooseX::Declare - perl

Moose is very lovely, but sometimes simple typos can cause hair-raisingly exciting long stacktraces with, from my point of view, zero useful content.
So, are there any tools to interpret this exploding into something helpful?
In particular for classes using plain Moose, Moose+MooseX::Method::Signatures, and MooseX::Declare.
The tools only need to be helpful while developing to catch those typo or thinko problems that make things just not work.
=========================
Following suggestion below, I'm using this not-quite-a-module-yet which is reducing my headaches a little, more ideas welcome, though:
package MooseX::QuietCarping;
# Not actually a Moose thing, but helpful for Moose.
# calm Moose-internal stacktraces down a little
use Carp;
my %retain = ();
sub import {
my $class = shift;
$retain{$_}++ for #_;
}
CHECK {
for (sort keys %INC) {
s{\.pm$}{};
s{[/\\]}{::}g; # CROSS PLATFORM MY ARSE
next if $retain{$_};
$Carp::Internal{$_}++ if /^(?:Class::MOP|Moose|MooseX)\b/
}
%retain = (); # don't need this no more
}
1;

One way I experimented with some time ago is putting Moose related classes into %Carp::Internal hash, something like this:
$Carp::Internal{$_}++ for qw{
Class::MOP
Class::MOP::Attribute
Class::MOP::Class
...
};
Such classes will be skipped in stack trace, making it more compact and emphasizing your own code.
You can find them by traversing %INC variable:
package Dummy;
use Moose;
use MooseX::Declare;
# use ....;
for (sort keys %INC) {
s{\.pm$}{};
s{/}{::}g;
print "$_\n" if /^(Class::MOP|Moose|MooseX)\b/;
}

I seem to recall seeing a PerlMonks post by stvn a week or two ago saying that they're working on improving the Moose error messages. I don't think there's anything currently available to clean the up, though.

Method::Signatures::Modifiers is a package which hopes to fix some of the problems of MooseX::Method::Signatures. Simply use it to overload.
use MooseX::Declare;
use Method::Signatures::Modifiers;
class Foo
{
method bar (Int $thing) {
# this method is declared with Method::Signatures instead of MooseX::Method::Signatures
}
}

Related

What is the best practice for finding all the superclasses of a Perl class?

Is there a standard CPAN way of finding out all the superclasses of a Perl class (or better yet entire superclass tree, up to UNIVERSAL)?
Or is the best practice to simply examine #{"${$class}::ISA"} for each class, class's parents etc?
There is no "standard way" because this is not a standard thing you want to do. For anything other than visualization it is an OO red flag to want to inspect your inheritance tree.
In addition to Class::ISA, there is mro::get_linear_isa(). Both have been in core for a while so they could be considered "standard" for some definition. Both of those show inheritance as a flat list, not a tree, which is useful mostly for deep magic.
The perl5i meta object provides both linear_isa(), like mro (it just calls mro), and ISA() which returns the class' #ISA. It can be used to construct a tree using simple recursion without getting into symbol tables.
use perl5i::2;
func print_isa_tree($class, $depth) {
$depth ||= 0;
my $indent = " " x $depth;
say $indent, $class;
for my $super_class ($class->mc->ISA) {
print_isa_tree($super_class, $depth+1);
}
return;
}
my $Class = shift;
$Class->require;
print_isa_tree($Class);
__END__
DBIx::Class
DBIx::Class::Componentised
Class::C3::Componentised
DBIx::Class::AccessorGroup
Class::Accessor::Grouped
I think Class::ISA is something like you are looking for
use Class::ISA;
use Mojolicious;
print join "\n", Class::ISA::super_path("Mojolicious");
Prints:
Mojo
Mojo::Base
However, it's not some kind of "best practice" since the whole task isn't something Perl programmers do every day.
Most likely these days you want to use one of the functions from mro, such as mro::get_linear_isa.
use mro;
my #superclasses = mro::get_linear_isa($class);
I don't believe that there is something like a "standard CPAN way". Examining #ISA is common practice - and also plausible, since techniques like use base qw(...) and use parent -norequire, ... also operate on top of #ISA...

How can I conditionally import a package in Perl?

I have a Perl script which uses a not-so-common module, and I want it to be usable without that module being installed, although with limited functionality. Is it possible?
I thought of something like this:
my $has_foobar;
if (has_module "foobar") {
<< use it >>
$has_foobar = true;
} else {
print STDERR "Warning: foobar not found. Not using it.\n";
$has_foobar = false;
}
You can use require to load modules at runtime, and eval to trap possible exceptions:
eval {
require Foobar;
Foobar->import();
};
if ($#) {
warn "Error including Foobar: $#";
}
See also perldoc use.
Consider the if pragma.
use if CONDITION, MODULE => ARGUMENTS;
I recommend employing Module::Load so that the intention is made clear.
Edit: disregard the comments, Module::Load is in core.
Another approach is to use Class::MOP's load_class method. You can use it like:
Class::MOP::load_class( 'foobar', $some_options )
It throws an exception so you'll have to catch that. More info here.
Also, while this isn't necessarily on every system Class::MOP is awfully useful to have and with Moose becoming more prevalent every day it likely is on your system.

To bless or not to bless, that is my question!

first post from a newbie-user. Every question I google seems to bring me here and I always get a great answer to what I'm looking for; so naturally this was my first stop when I began pondering the usage of blessing in Perl.
I've just gotten into Perl's OOP and just today read the post asking what bless does. I now understand that it references a scalar/hash/array to an object, 'attaching' it, if you will.
In most of the examples of classes I see in Perl, they don't seem to have properties like I'm used to seeing in other languages...
{ package Person;
my $property = "This is what I'm talking about :)";
sub new { ... }
...
}
So, I created a stupid class with a property to see what would happen. I gave the property the value 'NIL' right off the bat and then 'Not Nil!' in the constructor. Using a method LIST, I was able to print the property, and as I expected, it printed 'Not Nil!'
My question is, if properties work the same as I expected them to work (declared in the body) then why use bless at all? What is the added benefit of having that reference when you could simply create a scalar/hash/array as a property, or create whatever references you want as a property?
I hope I explained what I'm trying to ask well enough, very green with Perl :)
Well, that is not how you create classes in Perl.
Your $property variable is defined in package scope. Therefore, there will only one copy of it per class rather than each object having its own copy.
One might implement such a class using hash based objects the long and hard way as below:
#!/usr/bin/perl
package Person;
use strict; use warnings;
sub new {
my $class = shift;
my $self = {};
bless $self => $class;
my ($arg) = #_;
for my $property ( qw( message ) ) {
if ( exists $arg->{$property} ) {
$self->$property($arg->{$property});
}
}
return $self;
}
sub message {
my $self = shift;
return $self->{message} unless #_;
my ($msg) = #_;
$self->{message} = $msg;
}
package main;
my $person = Person->new({
message => "This is what I'm talking about :)"
});
print $person->message, "\n";
Now, this gets tedious fast. So, there are modules that help you deal with this as well as helping you define your classes in way that is safe for inheritance.
Class::Accessor is one such utility module.
For programs where startup time is not an issue, you should consider Moose. With Moose, you can write the above as:
#!/usr/bin/perl
package Person;
use Moose;
has 'message' => (is => 'rw', isa => 'Str');
__PACKAGE__->meta->make_immutable;
no Moose;
package main;
my $person = Person->new({
message => "This is what I'm talking about :)"
});
print $person->message, "\n";
You should read perldoc perltoot and Moose::Manual::Unsweetened for the standard way of doing things.
What you did with $property in this case is declared a variable in the "Person" package's scope. You change that inside (or outside using $Person::property) of the package, and any object that refers to it will see the updated variable, so it acts a lot like a "static attribute (Java)" without any real "private" scope. By convention, hidden things in Perl ("private" or "protected") are prefixed with an underscore, but of course this isn't enforced.
You don't actually make a new class, as you pointed out, with the "package" keyword; you can use "package" without OOP at all. That simply creates a separate "namespace".
The advantage of "blessing" a variable, almost always a hash reference from what I've seen, is that you can have methods, just like any other OOP language. Just remember to bless whatever you return in the new {} subroutine ("new" isn't actually a reserved word; just a convention). When you call a method on the "object" (a blessed data structure like a hashref), the first argument of the method is the data structure itself. So, if you have a hashref called $myobject, which is blessed to AwesomeClass, and you define a method in AwesomeClass called doSomethingAwesome, which needs to accept one variable, you would have to "shift" #_ (which is the argument list of the subroutine, or use $_[0]) to access the $myobject hashref. Python does something similar, and all languages pass the object reference to the method somehow. ("this" keyword in many, see also "thiscall" calling convention)
NB: I've seen lots Perl bashing in my time, which has only been a few years as a programmer. Perl is an awesome language that was made by a very smart linguist (Larry Wall) and has a fanatical following -- more fanatical at one time than Ruby, perhaps, but not as much as David Koresh). Perl does things very differently than lots of languages but if you look at code golf entries on this site and others, you can clearly see that much can be accomplished with very little Perl (no guarantees about code legibility, especially for newcomers!)
The value of bless'ing an object is getting to use the methods from a particular package.
package MyClass;
sub answer { my ($self)=#_; return $self->{foo} * 42; }
package main;
my $object1 = { foo => 1, bar => "\t" };
my $object2 = bless { foo => 2, bar => "\t" }, "MyClass";
$ref1 = ref $object1; # 'HASH'
$ref2 = ref $object2; # 'MyClass'
$answer1 = $object1->answer; # run time error
$answer2 = $object2->answer; # calls MyClass::answer, returns 2 * 42 = 84
Ugh... Sinan's answer is entirely too learned for my taste, at least past 12am :)
So I'll give a shorter and somewhat less Perly one, just for variety's sake.
Your question is not really about Perl as far as I can tell, and can be just as easily ased in another form: "Why bother using C++ and OOP in it when C already has structs?"
In other words, you seem to be asking what the point of using OOP paradigm is.
The answer is of course that it helps solving certain software engineering problems easier than pure procedural programming. Emphasis on certain - OOP is not a panacea for every problem, any more than ANY technique/approach/paradigm is.
Using OOP (in a form of packages as classes and blessed hashes as objects in Perl) allows you to enjoy the benefits of inheritance, polymorphism and other OOPyish mumbo-jumbo which you are probably already fairly familiar with from you non-Perl OOP experience.
Can you do 100% of what you'd have done with a blessed object with a pure data structure? Absolutely. Would 100% of it be just as easy/short/readable/maintainable code as you can achieve using objects? Most likely not, though it depends on how well your OOP code actually leverages the benefits that OOP provides (BTW, I have encountered supposedly OOP code (Perl and not) which wasn't really taking any advantage of OOP paradigm and could have been made easier to read and understand had it been stripped of its OOP chrome).

How do I list available methods on a given object or package in Perl?

How do I list available methods on a given object or package in Perl?
There are (rather too) many ways to do this in Perl because there are so many ways to do things in Perl. As someone commented, autoloaded methods will always be a bit tricky. However, rather than rolling your own approach I would suggest that you take a look at Class::Inspector on CPAN. That will let you do something like:
my $methods = Class::Inspector->methods( 'Foo::Class', 'full', 'public' );
If you have a package called Foo, this should do it:
no strict 'refs';
for(keys %Foo::) { # All the symbols in Foo's symbol table
print "$_\n" if exists &{"Foo::$_"}; # check if symbol is method
}
use strict 'refs';
Alternatively, to get a list of all methods in package Foo:
no strict 'refs';
my #methods = grep { defined &{"Foo::$_"} } keys %Foo::;
use strict 'refs';
if you have a package that is using Moose its reasonably simple:
print PackageNameHere->meta->dump;
And for more complete data:
use Data::Dumper;
print Dumper( PackageNameHere->meta );
Will get you started. For everything else, theres the methods that appear on ->meta that are documented in Class::MOP::Class
You can do a bit of AdHoc faking of moose goodness for packages without it with:
use Class::MOP::Class;
my $meta = Class::MOP::Class->initialize( PackageNameHere );
and then proceed to use the Class::MOP methods like you would with Moose.
For starters:
$meta->get_method_map();
use Moose; #, its awesome.
In general, you can't do this with a dynamic language like Perl. The package might define some methods that you can find, but it can also make up methods on the fly that don't have definitions until you use them. Additionally, even calling a method (that works) might not define it. That's the sort of things that make dynamic languages nice. :)
What task are you trying to solve?
A good answer from How to get structure and inheritance history
The classes from which an object's class currently inherits can be found using the following:
use mro qw( );
use Scalar::Util qw( blessed );
say join ", ", #{ mro::get_linear_isa(blessed($o)) };

What's the best way to discover all subroutines a Perl module has?

What's the best way to programatically discover all of the subroutines a perl module has? This could be a module, a class (no #EXPORT), or anything in-between.
Edit: All of the methods below look like they will work. I'd probably use the Class::Sniff or Class::Inspector in production. However, Leon's answer is marked as 'accepted' since it answers the question as posed, even though no strict 'refs' has to be used. :-) Class::Sniff may be a good choice as it progresses; it looks like a lot of thought has gone into it.
sub list_module {
my $module = shift;
no strict 'refs';
return grep { defined &{"$module\::$_"} } keys %{"$module\::"}
}
ETA: if you want to filter out imported subroutines, you can do this
use B qw/svref_2object/;
sub in_package {
my ($coderef, $package) = #_;
my $cv = svref_2object($coderef);
return if not $cv->isa('B::CV') or $cv->GV->isa('B::SPECIAL');
return $cv->GV->STASH->NAME eq $package;
}
sub list_module {
my $module = shift;
no strict 'refs';
return grep { defined &{"$module\::$_"} and in_package(\&{*$_}, $module) } keys %{"$module\::"}
}
Class::Inspector:
Class::Inspector allows you to get information about a loaded class. Most or all of this information can be found in other ways, but they aren't always very friendly, and usually involve a relatively high level of Perl wizardry, or strange and unusual looking code. Class::Inspector attempts to provide an easier, more friendly interface to this information...
Have a look at this:
Class::Sniff
The interface is rather ad-hoc at the moment and is likely to change. After creating a new instance, calling the report method is your best option. You can then visually examine it to look for potential problems:
my $sniff = Class::Sniff->new({class => 'Some::Class'});
print $sniff->report;
This module attempts to help programmers find 'code smells' in the object-oriented code. If it reports something, it does not mean that your code is wrong. It just means that you might want to look at your code a little bit more closely to see if you have any problems.
At the present time, we assume Perl's default left-most, depth-first search order. We may alter this in the future (and there's a work-around with the paths method. More on this later)...