I have a problem when using a variable to reference a module, it seems to mess up the passing of the variables:
TOTO.pm
package TOTO;
use Data::Dumper;
sub print {
print Dumper(#_);
}
Perl program
package main;
TOTO::print('Hello World');
print ">>>>>>>>>>>\n";
my $package = 'TOTO';
$package->print('Hello World');
And the output is:
$VAR1 = 'Hello World';
>>>>>>>>>>>
$VAR1 = 'TOTO';
$VAR2 = 'Hello World';
Any advice on how to avoid having TOTO passed as the first variable?
Short: The observed behavior comes from use of -> on a package name.
The arrow operator is used with a reference or with an object, which itself is a reference to a data structure that has been bless-ed into its class. (Or with a class name, see below.) That object or the class name is quietly passed as the first argument so that the whole system would work. Note that the package in the question does not define a class (objects cannot be created with it).
From Arrow operator in perlop
"-> " is an infix dereference operator, just as it is in C and C++. If the right side is either a [...] , {...} , or a (...) subscript, then the left side must be either a hard or symbolic reference to an array, a hash, or a subroutine respectively. (Or technically speaking, a location capable of holding a hard reference, if it's an array or hash reference being used for assignment.) See perlreftut and perlref.
It continues, to statements of direct interest in this problem
Otherwise, the right side is a method name or a simple scalar variable containing either the method name or a subroutine reference, and the left side must be either an object (a blessed reference) or a class name (that is, a package name). See perlobj.
So in uses related to classes the left-hand side may contain the class name, and class methods can then be invoked on it (or it can be just queried). Given that a class is a package then this is a package name.
The situation in the question falls within this so the package name is passed to the subroutine. However, according to the above quote it seems that the sub can only be a method, which isn't the case here. So it may be that this use of -> should really be disallowed. Either way, using it on a package which isn't a class strikes me as mistaken.
Update to clarification. This use was intended, to resolve an ambiguity in which package was loaded. The package name is saved into a variable and then the sub invoked on it, using the arrow operator. In this case code would have to be added to the sub to handle the first argument (package name) which is passed regardless of the invocation, by the courtesy of the arrow operator. But then we would have to allow a case when this is invoked on an object, ending up with a code that covers two distinct uses. I believe that it is better to change to a design that does not involve all this.
If you want to use a package, say as a library
File TOTO.pm
pacakge TOTO;
use Exporter;
our (#ISA, #EXPORT_OK);
#ISA = ('Exporter');
#EXPORT_OK = qw(prn); # This can be asked for by user of package
use Data::Dumper;
sub prn {
print Dumper(#_);
}
1; # important for 'require' when this is used
I've changed the sub name to prn so that it's not a Perl library function. The main script
use warnings;
use strict;
use TOTO qw(prn);
prn("Hello World");
The fully qualified name TOTO::prn() can always be used. If you wanted to make this a class that would require a bit more in the package.
This package, TOTO, does not export anything by default, unless asked for. That's what #EXPORT_OK sets up and that's why we need to list functions to import into main:: when use TOTO. Start, for example, with perlmod
In the simplest terms, to create an object-oriented TOTO module you must create a file TOTO.pm that contains at least a constructor subroutine new
package TOTO;
sub new {
bless {};
}
sub print {
print "I am a TOTO object\n";
}
1;
That code must be saved in a file called TOTO.pmthat must match the package TOTO name in the source
Then you may write a program, say main.pl, that uses that module. For instance
use strict;
use warnings 'all';
use TOTO;
my $object = TOTO->new;
$object->print;
And then you have created a new TOTO object that says what it is
If I run
$ perl main.pl
I get the output
I am a TOTO object
You will want to make this code more useful, and there are many variations on this theme, but those are the basics
That's just how Perl's package system works. You need to handle this yourself in the sub being called. You can't change it prior to the call.
sub print {
# special variable __PACKAGE__ contains "TOTO"
if ($_[0] eq __PACKAGE__ || ref $_[0] eq __PACKAGE__){
shift; # throw away class/object
}
print Dumper(#_);
}
The ref $_[0] part isn't technically needed, because you don't have a constructor in your class (you call the method on the class only, but it will just do the right thing if you ever do use objects without having to change anything later).
Here's the issue
Any advice on how to avoid having TOTO passed as the first variable?
You've discovered the answer yourself. This works fine
TOTO::print('Hello World');
If you call it as
TOTO->print('Hello World');
then you're asking for perl to call print as a class method and pass ('TOTO', 'Hello World') as parameters to the TOTO::print subroutine
If TOTO is just a bunch of subroutines then, as you found, just call TOTO::totosub
Check differences between this:
TOTO::print("Hello World");
and
TOTO->print("Hello World");
which is not proper object notation, because TOTO is just a string.
Syntaxe object->function(arguments) whil pass object as 1st argument, to be stored as $this, for sample.
sub print {
my $this = shift #_;
print Dumper(#_);
}
May do the job (even if not blessed object).
Try this:
package TOTO;
use Data::Dumper;
sub new { return bless {}, shift; }
sub print {
my $self = shift #_;
if ( scalar $self =~ /=HASH\(/ ) {
print Dumper(#_);
} else {
print Dumper($self);
}
}
package main;
my $package = TOTO->new();
$package->print("Hello World");
TOTO::print("Hello World");
This could output:
$VAR1 = 'Hello World';
$VAR1 = 'Hello World';
And have a look at man perlobj, man perlootut and man perlmodlib
Related
I'm a Java/C/C#/python coder who is attempting his first Perl script, and I have what is prob a Perl OOO 101 question: What is the syntax to access an object's members when use strict is required?
Let me speak Java for a moment. I have this little program, all in one class file:
class Dude{
public String name;
public Dude(String name){
this.name = name;
}
public void IntroduceYourself(){
System.out.println("Hi, I'm "+this.name);
}
}
public toy(){
Dude fred = new Dude("Fred");
fred.IntroduceYourself();
}
Output on my Ubuntu machine:
me#ubuntu01:~/$ java toy
Hi, I'm Fred
me#ubuntu01:~/$
What could be simpler? I create a Dude object, then later call method Dude.IntroduceYourself(), which accesses a class member.
Okay: I have to do the exact same thing, but now in Perl (v5.26.1). Again, use strict; is required. Here's my miserable attempt:
#!/usr/bin/perl
use warnings;
use strict;
# Define a "Dude" class
package Dude;
sub new
{
my $class = shift;
my $self = {
_name => shift,
};
bless $self, $class;
return $self;
}
sub IntroduceYourself
{
print("Hi, I'm $object->{name}\n"); # Compilation Error here!
}
my $object = new Dude("Fred");
$object->IntroduceYourself();
Output on the same Ubuntu machine:
me#ubuntu01:~/$ ./toyPerl.pl
Global symbol "$Dude" requires explicit package name (did you forget to declare "my $Dude"?) at ./toyPerl.pl line 18.
Execution of ./toyPerl.pl aborted due to compilation errors.
me#ubuntu01:~/$
Ugh. I've been reading a few Perl tutorials, and I see examples on how to write that IntroduceYourself() subroutine, but none with use strict as a global directive. Can anyone see what I'm doing wrong?
Also: I'm really confused about what I'll call "member functions" in Perl. In my Java example, Dude.IntroduceYourself() was defined as a method of class Dude. I intend (if possible) for IntroduceYourself() to be a function of Object/Class Dude in the Perl code. But its unclear to me how to define that. Am I misunderstanding how Perl objects handle member functions? Thank you.
This doesn't have to do with OO, just Perl's normal strict behavior. strict forces you to declare variables, like in other languages. Without strict, undeclared objects are globals. $object is never declared, so it violates strict.
To solve this, $object must be declared. Perl's this is passed in as the first argument to a method. You need to get that argument. Perl calls this the "invocant". Typically it is called $self.
What is the syntax to access an object's members
Perl doesn't have object members like Java. A Perl object is just a reference. It doesn't even need to be a hash reference. $self->{key} is just using a hash reference, so the key has to match. $self->{_name} not $self->{name}.
sub IntroduceYourself {
# Get the invocant off the list of arguments.
my $self = shift;
# Use it as a hash reference with the correct key.
print("Hi, I'm $self->{_name}\n");
}
I intend (if possible) for IntroduceYourself() to be a function of Object/Class Dude in the Perl code. But its unclear to me how to define that.
You did it. A class is just a package. A method is just a subroutine in a package. The language does not make a distinction between subroutines and methods, nor between class and object methods. It's just how you use them.
#!/usr/bin/perl
use strict;
use warnings;
package Foo {
sub new {
my $class = shift;
my($name) = #_;
return bless { name => $name }, $class;
}
sub hello {
my $self = shift;
print "Hello my name is $self->{name}\n";
}
}
my $foo = Foo->new("Pete");
# Called as an object method.
$foo->hello;
# Called as a subroutine.
# It works, but don't do it; it bypasses inheritance.
Foo::hello($foo);
# Called as a class method.
# It "works", but since the method expects $self to be a
# reference, not a package name, $self->{name} is... it's complicated.
Foo->hello;
Perl's OO is extremely basic. You get classes (via packages), multiple-inheritance (via #ISA), and methods (via subroutines with the invocant passed in) and that's about it. No accessors, no public, no private, no members, not even this.
If you want that, you have to write it yourself, or use an existing library. If you want all the bells and whistles and a full marching band, install Moose.
...use strict as a global directive...
use strict is not global, it is local to the current scope. The current scope is the whole file, but you can put it in a block.
{
# strict is on in this block
use strict;
my $foo = 42;
print "$foo\n";
}
# strict is off everywhere else
$bar = 23;
print "$bar\n";
Things like strict and warnings are referred to as "pragmas".
See "What's the difference between dynamic and lexical (static) scoping? Between local() and my()?".
sub IntroduceYourself {
my $self = shift;
print( "Hi, I'm $self->{ _name }\n" );
}
See perlootut.
In OOP, the invocant (the value of the expression before the ./->) is passed to the method as an argument. In Java, this argument is made available as this. In Perl, this argument is made available as a leading parameter.
This means that
$o->foo( $x, $y )
is equivalent to
my $method = $o->can( 'foo' );
$method->( $o, $x, $y )
And the method looks like this:
sub foo {
my $self = shift;
my $x = shift;
my $y = shift;
$self->{ x } = $x;
$self->{ y } = $y;
}
Given a variable containing a string that represents the name of a package, how do I call a specific subroutine of the package?
Here's the closest thing I have figured out:
package MyPackage;
sub echo {
print shift;
}
my $package_name = 'MyPackage';
$package_name->echo('Hello World');
1;
The problem with this code is the subroutine is called as a class method; the package name is passed in as the first argument. I want to invoke the subroutine from the package name without a special first argument being implicitly passed in.
It sounds like you don't want to actually call it as a method, but as a regular subroutine. In that case, you can use a symbolic reference:
my $package_name = 'MyPackage';
{
no strict 'refs';
&{ $package_name . '::echo' }( 'Hello World' );
}
Perl method calls are just regular subroutines, which get the invocant as the first value.
use strict;
use warnings;
use 5.10.1;
{
package MyPackage;
sub new{ bless {}, shift } # overly simplistic constructor (DO NOT REUSE)
sub echo{ say #_ }
}
my $package_name = 'MyPackage';
$package_name->echo;
my $object = $package_name->new();
$object->echo; # effectively the same as MyPackage::echo($object)
MyPackage
MyPackage=HASH(0x1e2a070)
If you want to call a subroutine without an invocant, you will need to call it differently.
{
no strict 'refs';
${$package_name.'::'}{echo}->('Hello World');
&{$package_name.'::echo'}('Hello World');
}
# only works for packages without :: in the name
$::{$package_name.'::'}{echo}->('Hello World');
$package_name->can('echo')->('Hello World');
The can method returns a reference to the subroutine that would be called if it had been called on the invocant. The coderef can then be used separately.
my $code_ref = $package_name->can('echo');
$code_ref->('Hello World');
There are some caveats to using can:
can may be overridden by the package, or any class from which it inherits.
The package that defines a method may be different than the invocant.
This may actually be the behaviour you're looking for though.
Another approach is to use something called a symbolic reference.
{
no strict 'refs';
&{ $package_name.'::echo' }('Hello World');
}
Using symbolic references is usually not recommended. Part of the problem is that it is possible to accidently use a symbolic reference where you didn't intend on using one. This is why you can't have use strict 'refs'; in effect.
This may be the simplest way to do what you want to do though.
If you don't want to use a symbolic reference you could use the Stash.
$MyPackage::{echo}->('Hello World');
$::{'MyPackage::'}{echo}->('Hello World');
$main::{'MyPackage::'}{echo}->('Hello World');
$main::{'main::'}{'MyPackage::'}{echo}->('Hello World');
$main::{'main::'}{'main::'}{'main::'}{'MyPackage::'}{echo}->('Hello World');
The only problem with this is that you would have to split $package_name on ::
*Some::Long::Package::Name::echo = \&MyPackage::echo;
$::{'Some::'}{'Long::'}{'Package::'}{'Name::'}{echo}('Hello World');
sub get_package_stash{
my $package = shift.'::';
my #package = split /(?<=::)/, $package;
my $stash = \%:: ;
$stash = $stash->{$_} for #package;
return $stash;
}
get_package_stash('Some::Long::Package::Name')->{echo}('Hello World');
This isn't that big of a problem though. After a quick look on CPAN you find Package::Stash.
use Package::Stash;
my $stash = Package::Stash->new($package_name);
my $coderef = $stash->get_symbol('&echo');
$coderef->('Hello World');
(The Pure Perl version of Package::Stash uses symbolic references, not the Stash)
It's even possible to make an alias of the subroutine/method, as if had been imported from a module that was using Exporter:
*echo = \&{$package_name.'::echo'};
echo('Hello World');
I would recommend limiting the scope of the alias though:
{
local *echo = \&{$package_name.'::echo'};
echo('Hello World');
}
This is an exception, where you can use a symbolic reference with strict 'refs' enabled.
Use the &{ <EXPRESSION> }() syntax of calling a sub whose name is the expression, as discussed in perldoc perlref when listing dereferencing operators:
Admittedly, it's a little silly to use the curlies in this case, but the BLOCK can contain any arbitrary expression, in particular, subscripted expressions:
&{ $dispatch{$index} }(1,2,3); # call correct routine
Random practical example:
# Note no "use strict"!
use File::Slurp;
my $p="File::Slurp";
#a=&{"${p}::read_file"}(".profile");
print $a[0];
I'm working on a package that defines exceptions (using Exception::Class::Nested) for its 'parent' package. I don't want the parent package to have to use the really long names, though, and I don't want to pollute any other namespace.
So what I'd like to do is export the last element of the class names into the namespace of the package that used the exception package.
For example, an excerpt from the exception package:
package Klass:Foo::Bar::Exceptions;
use vars qw( #ISA #EXPORT #EXPORT_OK ... );
#ISA = qw( Klass::Foo::Bar Exporter );
use Exception::Class::Nested 0.04 (
'Klass::Foo::Bar::Exceptions::BaseClass' => {
description => 'Base class for exceptions',
'Klass::Foo::Bar::Exceptions::NameError' => {
error => "I don't like your face"
}
}
);
The 'parent' package:
package Klass::Foo::Bar;
use Klass::Foo::Bar::Exceptions;
Klass::Foo::Bar::Exceptions::NameError->throw(error => "D'oh!");
my $e = NameError->new(error => 'Mwahaha!');
I'd like to export/import the exception class such that the second invocation (the my $e one) works as though NameError was defined in Klass::Foo::Bar, but I haven't figured it out yet.
(And before anyone says 'but Exception::Class has the nifty alias thingy,' I'll point out that the alias name is linked specifically to the exception's throw method, so I can't use that for non-auto-thrown new invocations..)
One thing I tried is putting this in the exception package's importer sub (#snames is either an array of the fully-qualified exception classes (e.g., 'Klass::Foo::Bar::Exceptions::NameError'), or just the tail end (e.g., 'NameError'):
my $caller = caller();
$caller ||= 'main';
my #snames = #{$EXPORT_TAGS{exceptions}};
for my $exc (#snames) {
$exc =~ s/^.*:://;
no strict qw(subs refs);
*{"${caller}\:\:${exc}\:\:"} = \*{__PACKAGE__ . "\:\:${exc}\:\:"};
}
But this ends up requiring me to invoke the exceptions using Klass::Foo::Bar::NameError rather than just NameError. It seems it works, but too well.
I don't want to import NameError into main::!
Typeglobs and symbol tables are still a bit mysterious to me, I'm afraid.
I'm sure there's a way to do what I want (or else I'm doing something that I shouldn't altogether, but let's leave that alone for now). Can anyone help me with this?
Thanks!
In your example import sub, you are aliasing package stashes, which is not going to do what you want. Instead, you want to create subroutines with the shortened names that return the full package name:
sub import {
my $caller = caller;
for my $long (#{$EXPORT_TAGS{exceptions}}) { # for each full name
my ($short) = $long =~ /([^:]+)$/; # grab the last segment
no strict 'refs';
*{"$caller\::$short"} = sub () {$long}; # install a subroutine named
# $short into the caller's pkg
# that returns $long
}
}
Breaking apart that last line, sub () {$long} creates an anonymous subroutine that takes no arguments. The code reference contains the single variable $long which retains the value it had during the loop iteration. This is called a lexical closure, which basically means that the subroutine's compilation environment ($long and it's value) will persist as long as the subroutine does.
This anonymous subroutine is then installed into the caller's package with the $short name. The fully qualified name of a subroutine in the caller's package is caller::subname, which "$caller\::$short" constructs. This is then dereferenced as a typeglob *{ ... }. Assignment to a typeglob with a reference fills that slot of the typeglob. So assigning a code reference installs the subroutine.
Put another way, the following subroutine declaration:
sub short () {'a::long::name'}
means the same thing as:
BEGIN {*{__PACKAGE__.'::short'} = sub () {'a::long::name'}}
I have following code:
my $coderef = ${MyModule::MyTool->new};
but when I try
$coderef->();
i got error:
Not a CODE reference
How can I take reference to constructor (without calling it) and run referenced code late?
The ${...} is the scalar dereference operator, not the anonymous subroutine constructor. You want:
my $coderef = sub {MyModule::MyTool->new};
And if your constructor takes arguments, you could write it this way:
my $coderef = sub {MyModule::MyTool->new(#_)};
The two examples above do not address one issue, and that is preserving the functionality of caller. If your constructor needs this (many do not), you can use Perl's magic goto &sub syntax:
my $coderef = sub {unshift #_, 'MyModule::MyTool'; goto &{$_[0]->can('new')} };
That probably requires a little explanation. First, the module name is placed before any other arguments (which is what the new method will expect). Then I used the UNIVERSAL method ->can to retrieve the coderef for the new method. goto &{...} then jumps to that coderef using the current argument list.
EDIT: The comments below show that there is some confusion as to when you would need to use the longer third technique. Here is a short segment that shows the problem:
package Original;
sub new {say +(caller)[0]} # presumably some better use of caller
# or Carp (which uses caller)
package Encapsulate::Simple;
sub new {
my (undef, $invocant, $method) = #_;
sub {$invocant->$method(#_)}
}
package Encapsulate::Better;
sub new {
my (undef, $invocant, $method) = #_;
sub {unshift #_, $invocant; goto &{$invocant->can($method)}}
}
package main;
my $bad = Encapsulate::Simple->new(qw/Original new/);
$bad->(); # always prints 'Encapsulate::Simple'
my $good = Encapsulate::Better->new(qw/Original new/);
$good->(); # prints 'main' as it should
package another;
$bad->(); # erroneously prints 'Encapsulate::Simple' again
$good->(); # prints 'another' as it should
So in short, Encapsulate::Better's sub preserves the exact functionality of Original->new whereas Encapsulate::Simple permanently binds it to its package, breaking any encapsulated methods that use caller for anything.
Use \& to obtain a reference to a named function:
my $coderef = \&MyModule::MyTool::new;
This should work regardless of which package holds the new:
my $coderef = MyModule::MyTool->UNIVERSAL::can( 'new' );
So that if MyModule::MyTool does not implement their constructor, you can still get it's handle.
In Perl we can get the name of the current package and current line number Using the predefined variables like __PACKAGE__ and __LINE__.
Like this I want to get the name of the current subroutine:
use strict;
use warnings;
print __PACKAGE__;
sub test()
{
print __LINE__;
}
&test();
In the above code I want to get the name of the subroutine inside the function test.
Use the caller() function:
my $sub_name = (caller(0))[3];
This will give you the name of the current subroutine, including its package (e.g. 'main::test'). Closures return names like 'main::__ANON__'and in eval it will be '(eval)'.
caller is the right way to do at #eugene pointed out if you want to do this inside the subroutine.
If you want another piece of your program to be able to identify the package and name information for a coderef, use Sub::Identify.
Incidentally, looking at
sub test()
{
print __LINE__;
}
&test();
there are a few important points to mention: First, don't use prototypes unless you are trying to mimic builtins. Second, don't use & when invoking a subroutine unless you specifically need the effects it provides.
Therefore, that snippet is better written as:
sub test
{
print __LINE__;
}
test();
I was just looking for an answer to this question as well, I found caller as well, but I was not interested in the fully qualified path, simply the literal current package name of the sub, so I used:
my $current_sub = (split(/::/,(caller(0))[3]))[-1];
Seems to work perfectly, just adding it in for if anyone else trips over this questions :)
There special __SUB__ exists from perl-5.16.
use v5.16;
use Sub::Identify qw/sub_fullname/;
sub foo {
print sub_fullname( __SUB__ ); # main::foo
}
foo();
Actually you can pass to sub_fullname any subroutine reference (even anonymous):
use Sub::Identify qw/sub_fullname/;
sub foo {
print sub_fullname( \&foo ); # main::foo
print sub_fullname( sub{} ); # main::__ANON__
}
foo();