What happens on this my declaration? - perl

I know the title sounds funny, but I found this snippet somewhere:
my MyPackage $p1 = MyPackage->new;
What role does the name of the package serve in front of $p1?
EDIT: I'm running perl 5.10.1.

It checks for a package with the same name, and, as of now, is tied to the fields pragma which helps check for typos in field names.
For example:
package MyPackage;
use fields qw/ foo bar /;
sub new { fields::new(shift) }
Then if you try to run
use MyPackage;
my MyPackage $p1 = MyPackage->new;
print $p1->{notpresent}, "\n";
you get
No such class field "notpresent" in variable $p1 of type MyPackage at ...

From http://perldoc.perl.org/functions/my.html:
my TYPE EXPR : ATTRS
A my declares the listed variables to be local (lexically) to the enclosing block, file, or eval. If more than one value is listed, the list must be placed in parentheses.
The exact semantics and interface of TYPE and ATTRS are still evolving. TYPE is currently bound to the use of fields pragma, and attributes are handled using the attributes pragma, or starting from Perl 5.8.0 also via the Attribute::Handlers module.

In addition to use by fields, the lexical type is used by the experimental types pragma (available from CPAN).

Related

Why can we access the subroutine even after specifying it in EXPORT_FAIL?

Why, even after specifying subtract function in EXPORT_FAIL, am I able to access the function by defining it fully like mathematics::subtract? How can we completely make the function private?
package mathematics;
use Exporter;
#ISA = qw(Exporter);
#EXPORT = qw(add);
#EXPORT_FAIL = qw(subtract);
sub add() {
print("you can add numbers here"."\n");
}
sub subtract() {
print("you can subtract the numbers here"."\n");
}
1;
How can we completely make the function private???
You cannot. Perl doesn't have the concept of private or public.
You can however make it a lexical code reference and use that inside your code.
package Foo;
use strict;
use warnings;
my $_private = sub {
return "this is a secret";
}; # note the semicolon
sub bar {
return $_private->(); # call with reference syntax ->()
}
1;
As a lexical variable, it is now only accessible from within its scope. In this case, that scope is the file, not the package. So if you have multiple packages in one file, they can all see it. You cannot access it via a fully qualified name from outside the package.
By convention, things that should be handled as if they were private in Perl are named with a leading underscore _. That's how other developers know that something is not part of the public API of a module and that it's subject to change and should not be messed with. Of course that doesn't stop anybody from doing it, but generally there is no reason to stop them.
Also note that package names in Perl typically are written in camel case with the first letter being capitalised. Your package should be called Mathematics, and it should have use strict and use warnings.
From Perl 5.18, you can use lexical subroutines to achieve what you want. The documentation says this:
These subroutines are only visible within the block in which they are
declared, and only after that declaration:
# Include these two lines if your code is intended to run under Perl
# versions earlier than 5.26.
no warnings "experimental::lexical_subs";
use feature 'lexical_subs';
foo(); # calls the package/global subroutine
state sub foo {
foo(); # also calls the package subroutine
}
foo(); # calls "state" sub
my $ref = \&foo; # take a reference to "state" sub
my sub bar {
...
}
bar(); # calls "my" sub
p.s. Lexical subroutines are non-experimental from 5.26.

How to avoid global variable declaration when using Perl's dynamic scoping?

I am trying to write a perl script that calls a function written somewhere else (by someone else) which manipulates some of the variables in my script's scope. Let's say the script is main.pl and the function is there in funcs.pm. My main.pl looks like this:
use warnings;
use strict;
package plshelp;
use funcs;
my $var = 3;
print "$var\n"; # <--- prints 3
{ # New scope somehow prevents visibility of $pointer outside
local our $pointer = \$var;
change();
}
print "$var\n"; # <--- Ideally should print whatever funcs.pm wanted
For some reason, using local our $pointer; prevents visibility of $pointer outside the scope. But if I just use our $pointer;, the variable can be seen outside the scope in main.pl using $plshelp::pointer (but not in funcs.pm, so it would be useless anyway). As a side-note, could someone please explain this?
funcs.pm looks something like this:
use warnings;
use strict;
package plshelp;
sub change
{
${$pointer} = 4;
}
I expected this to change the value of $var and print 4 when the main script was run. But I get a compile error saying $pointer wasn't declared. This error can be removed by adding our $pointer; at the top of change in funcs.pm, but that would create an unnecessary global variable that is visible everywhere. We can also remove this error by removing the use strict;, but that seems like a bad idea. We can also get it to work by using $plshelp::pointer in funcs.pm, but the person writing funcs.pm doesn't want to do that.
Is there a good way to achieve this functionality of letting funcs.pm manipulate variables in my scope without declaring global variables? If we were going for global variables anyway, I guess I don't need to use dynamic scoping at all.
Let's just say it's not possible to pass arguments to the function for some reason.
Update
It seems that local our isn't doing any "special" as far as preventing visibility is concerned. From perldoc:
This means that when use strict 'vars' is in effect, our lets you use a package variable without qualifying it with the package name, but only within the lexical scope of the our declaration. This applies immediately--even within the same statement.
and
This works even if the package variable has not been used before, as package variables spring into existence when first used.
So this means that $pointer "exists" even after we leave the curly braces. Just that we have to refer to it using $plshelp::pointer instead of just $pointer. But since we used local before initializing $pointer, it is still undefined outside the scope (although it is still "declared", whatever that means). A clearer way to write this would be (local (our $pointer)) = \$var;. Here, our $pointer "declares" $pointer and returns $pointer as well. We now apply local on this returned value, and this operation returns $pointer again which we are assigning to \$var.
But this still leaves the main question of whether there is a good way of achieving the required functionality unanswered.
Let's be clear about how global variables with our work and why they have to be declared: There's a difference between the storage of a global variable, and visibility of its unqualified name. Under use strict, undefined variable names will not implicitly refer to a global variable.
We can always access the global variable with its fully qualified name, e.g. $Foo::bar.
If a global variable in the current package already exists at compile time and is marked as an imported variable, we can access it with an unqualified name, e.g. $bar. If a Foo package is written appropriately, we could say use Foo qw($bar); say $bar where $bar is now a global variable in our package.
With our $foo, we create a global variable in the current package if that variable doesn't already exist. The name of the variable is also made available in the current lexical scope, just like the variable of a my declaration.
The local operator does not create a variable. Instead, it saves the current value of a global variable and clears that variable. At the end of the current scope, the old value is restored. You can interpret each global variable name as a stack of values. With local you can add (and remove) values on the stack.
So while local can dynamically scope a value, it does not create a dynamically scoped variable name.
By carefully considering which code is compiled when, it becomes clear why your example doesn't currently work:
In your main script, you load the module funcs. The use statement is executed in the BEGIN phase, i.e. during parsing.
use warnings;
use strict;
package plshelp;
use funcs;
The funcs module is compiled:
use warnings;
use strict;
package plshelp;
sub change
{
${$pointer} = 4;
}
At this point, no $pointer variable is in lexical scope and no imported global $pointer variable exists. Therefore you get an error. This compile-time observation is unrelated to the existence of a $pointer variable at runtime.
The canonical way to fix this error is to declare an our $pointer variable name in the scope of the sub change:
sub change {
our $pointer;
${$pointer} = 4;
}
Note that the global variable will exist anyway, this just brings the name into scope for use as an unqualified variable name.
Just because you can use global variables doesn't mean that you should. There are two issues with them:
On a design level, global variables do not declare a clear interface. By using a fully qualified name you can simply access a variable without any checks. They do not provide any encapsulation. This makes for fragile software and weird action-at-a-distance.
On an implementation level, global variables are simply less efficient than lexical variables. I have never actually seen this matter, but think of the cycles!
Also, global variables are global variables: They can only have one value at a time! Scoping the value with local can help to avoid this in some cases, but there can still be conflicts in complex systems where two modules want to set the same global variable to different values and those modules call into each other.
The only good uses for global variables I have seen are to provide additional context to a callback that cannot take extra parameters, roughly similar to your approach. But where possible it is always better to pass the context as a parameter. Subroutine arguments are already effectively dynamically scoped:
sub change {
my ($pointer) = #_;
${$pointer} = 4;
}
...
my $var = 3;
change(\$var);
If there is a lot of context it can be come cumbersome to pass all those references: change(\$foo, \$bar, \$baz, \#something_else, \%even_more, ...). It could then make sense to bundle that context into an object, which can then be manipulated in a more controlled manner. Manipulating local or global variables is not always the best design.
There's too much wrong with your code to just fix it
You've used package plshelp in both the main script and the module, even though the main entry point is in main.pl and your module is in funcs.pm. That's just irresponsible. Did you imagine that the package statement was solely for advertising for help and it didn't matter what you put in there?
Your post doesn't say what is wrong with what you have written, but it's surprising that it doesn't throw an error.
Here's something close that does what you seem to expect. I can't really explain things as your own code is so far from working
Functions.pm
package Functions;
use strict;
use warnings;
use Exporter 'import';
our #EXPORT_OK = 'change';
sub change {
my ($ref) = #_;
$$ref = 4;
}
main.pl
use strict;
use warnings 'all';
use Functions 'change';
my $var = 44;
print "$var\n";
change(\$var);
print "$var\n";
output
44
4

perl module calls methods from a package that isn't imported

I was appalled to discover today that one of my perl modules uses another module, but doesn't import it.
However, I was shocked when I realized that this has never caused any problems!
The code is something like:
package This;
# no import for OTHER !!
sub new {
... implementation ...
my $something = OTHER->new(#arguments); # no error!
... more implementation ...
}
So what gives? None of This's imports import OTHER -- that was the first thing I checked.
Could it be that if the code that imports This also imports OTHER, OTHER is available to This?
Clarification of question:
X, Y, and Z are modules.
in X: use Y;
in X: use Z;
Y does not use Z
Does Y have access to the functions and methods in Z (and vice versa)?
Your use of the term "import" is a bit misleading.
Does Y have access to Z without importing it (and vice versa)?
Yes, more or less. useing a module just loads it into the current script; all used modules are loaded into the same script, so can see each other (provided they're used in the right order).
But true imports — the things that a module actually exports, so that they're copied into the useing module's namespace — will only be copied into the useing module's namespace.
For example, consider this Perl script:
use Time::HiRes 'time';
package Foo;
sub time1() { return time(); } # calls the built-in time() function
sub time2() { return Time::HiRes::time(); }
package main;
print Foo::time1(), "\n"; # prints (e.g.) 1323048440
print Foo::time2(), "\n"; # prints (e.g.) 1323048440.80571
print time(), "\n"; # prints (e.g.) 1323048440.8061
It uses the Time::HiRes module, and tells it to export Time::HiRes::time into the current namespace (the main namespace), overwriting the built-in time. (Time::HiRes::time is like time, but it has sub-second resolution; it'll give something like 1323048440.80571 instead of just 1323048440.) So package Foo can see Time::HiRes, and anything within Time::HiRes, such as its time; but it has to explicitly specify that, by explicitly writing Time::HiRes::time.
(Note: I wrote the above as a single script, for simplicity of description, but the same thing happens when Foo is defined in Foo.pm and loaded using use Foo;.)
Yes, at least when you use indirect package and object syntax. From calls like
OtherPackage->method()
$anOtherPackageObject->method()
Perl can resolve a fully qualified subroutine name (&OtherPackage::method in both of the above cases) and invoke the subroutine from anywhere.

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 is the difference between package, module and class in object oriented Perl?

What is the difference between package, module and class in object oriented Perl?
Modules are a single file, a .pm file that provides code. That could be no packages, a single package, or more than one package. A module doesn't really care what is in it, so it can be code that inserts itself into the same namespace, a more-traditional set of subroutines in a library or define Perl's idea of a class.
A package, also known as a namespace, contains its own variables and subroutines. It's a way of segregating different parts of your program. You create the package and put your code into it:
package SomePackage;
sub some_subroutine { ... } # really SomePackage::some_subroutine
You load the module to get access to the package:
use SomePackage; # read and compile the module file
SomePackage::some_subroutine( ... );
A Perl class is a package and its associated behavior. The methods in a class are just normal subroutines, although when we treat the subroutines as methods, the first parameter is the thing (a package name or object, also known as the referent) that called method:
package SomeClass;
sub class_method { my( $class, #args ) = #_; ... }
sub instance_method { my( $self, #args ) = #_; ... }
Since the class is just a package like any other package and probably lives in a module, you access it the same way with use:
use SomeClass;
my $i = SomeClass->class_method( ... );
The OO arrow syntax does some special stuff to let the some_method subroutine know that it's being called as a method. Perl puts the referent (the SomeClass in this case) as the first argument. Additionally, when using the OO syntax, Perl knows to use its inheritance features.
Methods called with '->' get the referent as the first parameter to the method, so this call:
SomeClass->new('world');
is syntactically the same as if you had called it with the class name as the first parameter:
SomeClass::new( 'SomeClass' ,'world'); # no inheritance this way
That works the same for objects too. When an object is the referent:
my $i = SomeClass->new();
$i->bar( 'world');
the object is the first parameter as the method:
SomeClass::bar($i, 'world');
Perl doesn't have classes. It has namespaces that you change with package. For the complete details of Perl OOP, see Intermediate Perl or Object Oriented Perl. You can also see the perltoot and perlboot documentation. In short, Perl fakes what people expect "real" classes to be with packages, normal subroutines, and references.
A module is a distributable piece of code contained in a file. See perlmod.
I say more about this in my post for The Effective Perler, Find a module's release managers. I don't get into the OO stuff, but I talk about the other terms around "module".