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

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...

Related

Query in Perl Subroutines

I've to use perl as a part of our internship, I've come across this piece of code and could not understand what this may mean.
$val->ReadSim($first_sim, \&DataProcessing);
In the script, subroutine DataProcessing is defined, but could not find ReadSim. I tried searching in our infrastructure but was not able to. This was given to me to understand a week ago and I can't ask the guide without losing credits...
Please help...
What you're seeing is not a mere subroutine, but a method on some object called $val.
I take it you might see something on top of the program like this:
use Foo::Bar; # Some Perl module
This Perl module will contain the method ReadSim. Somewhere in your code, you probably see something like this:
my $val = Foo::Bar->new; # If the people who wrote this followed standards...
This defines $val as an object of Foo::Bar. If you look in package Foo::Bar, you'd see something like this:
#! Foo/Bar.pm
package Foo::Bar;
use strict; # Because I'm an optimist
use warnings;
...
sub new {
my $class = shift;
...
my $self = {};
...
bless $self, $class;
...
return $self; # May simply be bless {}, $class;
}
Then further down, you'll see:
sub ReadSim {
my $self = shift;
...
}
The $self = {} is a reference to a Perl hash. This is how most objects are defined. That's pretty much all the constructor does. It defines a reference to something, then blesses it as that object type. Then, the methods are merely subroutines that take the defined object and manipulate that.
$val-> ReadSim(...);
is equivalent to:
Foo::Bar::ReadSim( $val, ... );
So much for your introduction to Object Oriented Perl by Fire. You still have a question about what does ReadSim mean.
If all is right in the world, the developer of that module should have created built in Perl documentation called POD. First, determine the type of object $val is. Look where $val is defined (Something like my $val = Foo::Bar->new(...);). The Foo::Bar is the class that $val is a member of. You can do this from the command line:
$ perldoc Foo::Bar
And, if you're lucky, you'll see the documentation for Foo::Bar printed out. If you're really, really lucky, you will also see the what ReadSim also does.
And, if you're not so lucky, you'll have to do some digging. You can do this:
$ perldoc -l Foo::Bar
/usr/perl/lib/perl5/5.12/Foo/Bar.pm
This will print out the location of where the Perl Module resides on your system. For example, in this case, the module's code is in /usr/perl/lib/perl5/5.12/Foo/Bar.pm. Now, you can use an editor on this file to read it, and search for sub ReadSim and find out what that subroutine ... I mean method does.
One final thing. If you're new to Perl, you may want to look at a few tutorials that come with Perl. One is the Perl Reference Tutorial. This tutorial will tell you about references. In standard Perl, there are three different types of variables: scalar, hashes, and arrays. To create more complex data structures, you can create hashes of hashes or hashes of arrays, or arrays of arrays, etc. This tutorial will teach you about how to do this.
Once you understand references, you should read the tutorial on Perl Object Oriented Programming. Object Oriented Perl uses references to create a simulated world object oriented programming design. (I say simulated because some people will argue that Object Oriented Perl isn't really object oriented since you don't have things like private methods and variables. To me, if you can think in terms of objects and methods as you program, it's object oriented).

Intercept nonexistent methods call in Perl

I try to intercept nonexistent methods call in some subclass.
Yes, I know about AUTOLOAD,
but (for methods) it try to call parent::method first, then UNIVERSAL::method and only then ::AUTOLOAD.
But I need call (something like) ::AUTOLOAD at first.
Because I want to know what methods subclass try to call from parent.
Give me some advice about it please.
If you just want to know what methods are being used, you can use some profiling module like Devel::NYTProf.
If you want to react to that during your program execution, you can intercept directly the entersub opcode just as the profiling modules do. See the perlguts or profiling module code for more details.
You could probably create a 'Monitor' class with FETCH and EXISTS and tie it to the symbol table hash like: tie %Module::Name:: , Monitor;
But unless we know exactly what you are trying to do and why, it's hard to guess what would be the right solution for you.
Please heavily consider Jiri Klouda's suggestion that you step back and reconsider what you are trying to accomplish. You almost never want to do what you're trying to do.
But, if you're really sure you want to, here's how to get enough pure Perl rope to hang yourself...
The subs pragma takes a list of sub names to predeclare. As tchrist says above, you can predeclare subs but never actually define them. This will short-circuit method dispatch to superclasses and call your AUTOLOAD immediately.
As for the list of sub names to pass to the pragma, you could use Class::Inspector->methods (thanks to Nic Gibson's answer for teaching me about this module).
According to brian d foy's comment to Nic Gibson's answer, Class::Inspector will not handle methods defined in UNIVERSAL. If you need to do those separately, you can get inspiration from the 'use subs' line in my Class::LazyObject module.
Why not create an AUTOLOAD sub in the sub-class package which 1) reports the missing method and then 2) dispatches the call to the parent. For this to work you don't defined #ISA in the sub-class.
Something like:
package my_parent;
sub foo { warn "in my_parent::foo" }
package my_subclass;
my $PARENT_CLASS = "my_parent"; # assume only one parent
# Note: no #ISA defined here
sub AUTOLOAD {
warn "non-existent method $AUTOLOAD called\n";
my $self = shift;
(my $method = $AUTOLOAD) =~ s{.*::}{};
my $super = $PARENT_CLASS . '::' . $method;
$self->$super(#_);
}
package main;
my $x = bless {}, 'my_subclass';
$x->foo;
The syntax: $self->$super(#_) where $super has double-colons in it tells perl in which package to start looking for the method, e.g.:
$self->my_parent::foo(...)
will look for the foo method starting in the package my_parent regarless of what class $self is blessed into.

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).

Do Perl subclasses inherit imported modules and pragmas?

Lets say you have a parent Perl class in one file:
#!/usr/bin/perl
package Foo;
use strict;
use warnings;
use Data::Dumper;
sub new{
my $class = shift;
my %self = ();
return bless %self, $class;
}
1;
and a subclass in a different file:
#!/usr/bin/perl
package Bar;
use base "Foo";
1;
Will the subclass inherit the use statements from the parent? I know the method new will be inherited.
Basically I am trying to reduce the amount of boilerplate in my code and I can't find a clear answer to this question.
You asked in a comment about Test::Most and how it reduces boilerplate. Look at its import method. It's loading the modules into its namespace, adding those symbols to #EXPORT, then re-calling another import through a goto to finally get them into the calling namespace. It's some serious black magic that Curtis has going on there, although I wonder why he just didn't use something like import_to_level. Maybe there are some side effects I'm not thinking about.
I talk quite a bit about this sort of thing in Avoid accidently creating methods from module exports in The Effective Perler. It's in a different context but it's some of the same issues.
Here's a different example.
If some other module loads a module, you have access to it. It's not good to depend on that though. Here are three separate files:
Top.pm
use 5.010;
package Top;
use File::Spec;
sub announce { say "Hello from top!" }
1;
Bottom.pm
package Bottom;
use parent qw(Top);
sub catfiles { File::Spec->catfile( #_ ) }
1;
test.pl
use 5.010;
use Bottom;
say Bottom->catfiles( qw(foo bar baz) );
say File::Spec->catfile( qw( one two three ) );
I only load File::Spec in Top.pm. However, once loaded, I can use it anywhere in my Perl program. The output shows that I was able to "use" the module in other files even though I only loaded it in one:
Bottom/foo/bar/baz
one/two/three
For this to work, the part of the code that loads the module has to load before any other part of the code tries to use that module. As I said, it's a bad idea to depend on this: things break if the loading sequence changes or the loading module disappears.
If you want to import symbols, however, you have to explicitly load the module you want while you are in the package you want to import into. That's just so the exporting module defines the symbols in that package. It's not something that depends with scope.
Ah, good question!
Will the subclass inherit the use statements from the parent?
Well this depends on what you mean by inherit. I won't make any assumptions until the end, but the answer is maybe. You see, perl mixes the ideas of Classes, and Namespaces -- a package is a term that can describe either of them. Now the issue is the statement use all it does is force a package inclusion, and call the targets import() sub. This means it essentially has unlimited control over your package - and by way of that your class.
Now, compound this with all methods in perl being nothing more than subs that take $self as a first argument by convention and you're left with perl5. This has an enormous upside for those that know how to use it. While strict is a lexical pragma, what about Moose?
package BigMooseUser;
use Moose;
package BabyMooseUser;
our #ISA = 'BigMooseUser';
package Foo;
my $b = BabyMooseUser->new;
print $b->meta->name;
Now, where did BabyMooseUser get the constructor (new) from? Where did it get the meta class from? All of this is provided from a single use Moose; in the parent class (namespace). So
Will the subclass inherit the use statements from the parent?
Well, here, in our example, if the effects of the use statement are to add methods, than certainly.
This subject is kind of deep, and it depends if you're talking about pragmas, or more obscure object frameworks, or procedural modules. If you want to mitigate a parents namespace from affecting your own in the OO paradigm see namespace::autoclean.
For boilerplate reduction, I have a couple of strategies: Most of my classes are Moose classes, which takes care of OO setup and also gives me strict and warnings. If I want to have functions available in many packages, I'll create a project specific MyProject::Util module that uses Sub-Exporter to provide me with my own functions and my own interface. This makes it more consistent, and if I decide to change the Dumper (for example) later for whatever reason, I don't have to change lots of code. That'll also allow you to group exports. A class then usually looks something like this:
package Foo;
use Moose;
use MyProject::Util qw( :parsing :logging );
use namespace::autoclean;
# class implementation goes here
1;
If there's other things you regard as boilerplate and want to make simpler to include, it of course depends on what those things are.
A pragmatic answer to your problem: Either use, or look at how Modern::Perl does it to enforce strict and warnings.
You can get a definitive answer by examining the symbol tables for each package:
# examine-symbol-tables.pl
use Bar;
%parent_names = map{$_ => 1} keys %Foo::;
%child_names = map{$_ => 1} keys %Bar::;
delete $parent_names{$_} && ($common_names{$_} = delete $child_names{$_}) foreach keys %child_names;
print "Common names in symbol tables:\n";
print "#{[keys %common_names]}\n\n";
print "Unique names in Bar symbol table:\n";
print "#{[keys %child_names]}\n\n";
print "Unique names in Foo symbol table:\n";
print "#{[keys %parent_names]}\n\n";
$ perl inherit.pl
Common names in symbol tables:
BEGIN
Unique names in Bar symbol table:
ISA isa import
Unique names in Foo symbol table:
Dumper new VERSION

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)...