Skip Menu |

This queue is for tickets about the Class-Std CPAN distribution.

Report information
The Basics
Id: 26612
Status: rejected
Priority: 0/
Queue: Class-Std

People
Owner: Nobody in particular
Requestors: GLEACH [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: v0.0.8
Fixed in: (no value)



Subject: Order of class definition with respect to use is critical
This may just be a reflection of my own cluelessness, but it seems to me that Perl is indifferent to the order in which things are processed. Perhaps that's too broad an assertion, but I've never tripped across a contradiction until attempting to familiarize myself with inside-out classes and Class::Std. I took an existing script and added a class at the end of the file, with the call to Class::Std->new in the (higher up) body. "use class" is not required in this context. The expected operation of :ATTR( :name<foo ) wasw not happening, although the relevant code in Class::Std was being exeuted. Moving the class definition above the use in the file resolved the problem. To see this, take the file t/perlattrs.t from the distribution (which passes, of course) and move the statements for package main to the top of the file. It now fails. I assume that this is a Perlish thing. However a warning (<strong>!) in the POD would be appreciated.
Subject: Re: [rt.cpan.org #26612] Order of class definition with respect to use is critical
Date: Wed, 25 Apr 2007 14:34:21 +1000
To: bug-Class-Std [...] rt.cpan.org
From: Damian Conway <damian [...] conway.org>
Show quoted text
> This may just be a reflection of my own cluelessness, but it seems to me > that Perl is indifferent to the order in which things are processed.
I'm afraid that's not true. Perl runs in five distinct phases: BEGIN, CHECK, INIT, RUN, END. Within each phase the file is processed top-to-bottom. The tricky bit is that some components of the class set-up for Class::Std don't happen at BEGIN time (i.e. at compile-time). So if the class definition hasn't been finalized, it's only natural that the class won't work properly. This is not limited to Class::Std. In many cases, ordinary hash-based classes will fail to work correctly if placed after the code that uses them. For example: my $obj = Derived->new(); $obj->print(); package Base; sub new { my ($classname) = @_; return bless {}, $classname; } sub print { print "Hi there!\n" } package Derived; @ISA = qw( Base ); It's not even limited to OO Perl. This doesn't work either: foo(); # and later: my $STD_FOO_MESSAGE = "Hello, foo!\n"; sub foo { print $STD_FOO_MESSAGE; } If you really do want to place class definitions *after* code that uses them, the solution is to explicitly ensure that they are processed at compile-time, by putting them in a BEGIN block: my $obj = Derived->new(); $obj->print(); BEGIN { package Base; sub new { my ($classname) = @_; return bless {}, $classname; } sub print { print "Hi there!\n" } package Derived; @ISA = qw( Base ); } Damian
From: dmuey [...] cpan.org
On Tue Apr 24 14:46:29 2007, GLEACH wrote: Show quoted text
> This may just be a reflection of my own cluelessness, but it seems to me > that Perl is indifferent to the order in which things are processed.
Maybe the confusion from use() being essentially BEGIN which is why you can use Foo at the end and use Foo->methods before it. This should illustrate it: multivac:~ dmuey$ perl -le 'CGI->new;use CGI;' multivac:~ dmuey$ multivac:~ dmuey$ perl -le 'CGI->new;require CGI;' Can't locate object method "new" via package "CGI" at -e line 1. multivac:~ dmuey$ multivac:~ dmuey$ perl -le 'require CGI;CGI->new;' multivac:~ dmuey$