http://qs321.pair.com?node_id=11124056


in reply to Re^4: help with versioning modules
in thread help with versioning modules

Is it correct that in the context of a "use" statement (example: use My::Foo), the :: effectively represent a filesystem directory separator character (e.g. '/' in Linux), the last word with a ".pm" appended to it represents the module's filename, and this path (My::Foo, e.g. /My/Foo.pm) is then appended to each base path in @INC to determine where Perl will search for the listed module?
Correct, or close enough for all practical purposes. (What you describe matches my understanding of it, but I suspect there may be some subtle edge case which prevents it from being absolutely 100% accurate.)
If I'm understanding everything correctly, my original example is failing because the use My::Foo 1.0 statement is using My::Foo as a search path to find My/Foo.pm (relative to /home/user/perl_modules/lib/perl5) but it is also treating My::Foo as a package name to look for a version variable My::Foo::$VERSION. The only way both of these can be correct is if the package name matches the exact name specified to use the module.
Yep. And that makes two cases where it matters to Perl whether the two names match up - I never include version reuirements in use, so I forgot about that one.
I was able to fix this by adding a "1;" to the end of Bar.pm. Do all packages need to end with "1;"?
All files included via use or require need to return a true value (not the number 0, the string "0", the empty string, or undef) from the last statement in the file. Putting the line 1; at the end of the file is the standard way to ensure that this happens.

If the print statement in my example module had been outside the sub, it would have sufficed, but, because it's inside a sub which doesn't get called, it doesn't actually run when the file is loaded, so the file inclusion returns undef instead. (Oops. That's what I get for not testing my example code.)

What exactly is the difference between calling say_it with :: vs ->?
:: just specifies the package, so that you can directly call a sub or access a variable that's defined in a package other than the current package. It doesn't actually do anything other than letting you give the "full name" of a symbol.

-> is a part of how Perl does object-orientation and has a little bit of magic to let it fulfill that role. The first bit of magic is that, if you have a blessed reference to the left of the arrow, it will look for the right side in the package that the left side was blessed into. The second magical effect is that, when the sub on the right side is called, then whatever is on the left side of the arrow is passed as the first parameter, prior to any parameters that are explicitly given. (Which is what my comment earlier was referring to - if you don't look at the parameters, the extra one doesn't matter.)

I realize that explanation of the magic is so brief as to be unclear, so here are some examples:

Xyzzy::say_it; # Calls sub say_it in package Xyzzy with an empty parameter list Xyzzy->say_it; # Calls sub say_it in package Xyzzy with the parameters ('Xyzzy') my $obj = Some::Class->new(foo => 'bar'); # Calls sub new in package Some::Class with the parameters # ('Some::Class', 'foo', 'bar') # # By convention, 'new' will bless its return value into the class # (package) matching its first parameter ('Some::Class'), making # $obj an instance of that class $obj->do_stuff(1, 2, 3); # Because $obj is blessed as an instance of Some::Class, calls # Some::Class::do_stuff with the parameters ($obj, 1, 2, 3)