in reply to Perl OO: switch package context.

Just add my two cents. It's pretty easy to mix language constructs with conventions. Much of my experience with perl is first to learn to do the right thing, then to figure out whether it's required by the language or it's simply good practice. We all started using "use Foo::Bar::MyClass;" and "package Foo::Bar::MyClass;" from day one. It's pretty obvious what it must mean, especially if one comes from languages like java. But, like most other things perl, it's pretty loose about the three concepts: package, class and file. Here's my understanding (help me here, I'm not writing this with the confidence I'd like to have):
  1. The relation between "Foo::Bar::MyClass" and the file "Foo/Bar/MyClass.pm" is only required by the pragma "use", i.e., when you say "use Foo::Bar::MyClass;", it will look for the file "Foo/Bar/MyClass.pm", it says nothing about the content of the file.
  2. You can define any class in any file, i.e., in the file "Foo/Bar/MyClass.pm", you can define "package My::Other::FooClass;"
  3. The line "use Foo::Bar::MyClass;" typically introduces some namespaces, it only depends on what namespaces are defined in the file Foo/Bar/MyClass.pm, not the file name itself. This, when combined with item 2 above, means, even if you "use Foo::Bar::MyClass;", you may not even have the namespace "Foo::Bar::MyClass", instead, you may only be able to do "my $obj = My::Other::FooClass->new();". Of course, this would be confusing, so it's a convention to match the content of a file with the file name, not a requirement.
  4. There isn't a hiarchical relationship between "Foo::Bar::MyClass" and "MyClass" (that's why even in the file Foo/Bar/MyClass.pm, you still need to declare the full "Foo::Bar::MyClass", rather than simply "MyClass"), in fact, perl doesn't know the package "MyClass". What merlyn was refering to about symbol tables is that the implementation of symbol tables happen to split along "::", so the symbol table for "Foo::Bar::MyClass" can be found using "$::{'Foo::'}{'Bar::'}{'MyClass::'}":
    use strict; package Foo::Bar::MyClass; our $test = "test"; package main; print keys %{$::{'Foo::'}{'Bar::'}{'MyClass::'}}; __OUTPUT__ test