Skip Menu |

This queue is for tickets about the POE-Filter-XML CPAN distribution.

Report information
The Basics
Id: 22365
Status: rejected
Priority: 0/
Queue: POE-Filter-XML

People
Owner: nperez [...] cpan.org
Requestors: ewaters [...] uarc.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Empty subroutine prototypes
Date: Fri, 20 Oct 2006 09:58:25 -0600
To: via RT <bug-POE-Filter-XML [...] rt.cpan.org>
From: Eric Waters <ewaters [...] uarc.com>
Before I report another bug I'd like to say that I appreciate the work you've done on this software. I use this and a heavily modified POE::Component::Jabber (I'll show you the modifications at a later date) in an app I've been working on for the last few months. This bug applies to almost all the code you write. It appears that a style decision that you made (probably a long time ago) now causes compile-time errors in Perl v5.8.8 (and earlier versions, not sure how far back). It's also possible that this is a deliberate choice of yours. The problem is that every subroutine you write has an empty prototype: sub get_id() { my $self = shift; return $self->[+id]; } Normally this isn't an issue, as you call your subroutines as methods ($node->get_id()), and according to perlsub, method calls are not influenced by prototypes. But if you called it as a subroutine (so prototypes can be checked at compile time), you'd get a compiletime error: #!/usr/bin/perl use strict; use warnings; sub increment() { my $x = shift; return $x + 1; } my $number = increment(5); print "Have number $number\n"; Results in: Too many arguments for main::increment at ./prototype_test.pl line 13, near "5)" Execution of ./prototype_test.pl aborted due to compilation errors. If the only way you ever called these subroutines was as class methods, then this would never come up (the empty prototype would never be evaluated). You seem to have avoided this in the example of POE::Filter::XML::Node.pm by declaring data() (which calls _encode() and _decode()) before _encode() and _decode() (since the subroutines occur after their usage, they can't be checked at compile time), this means that no function below _decode() can use _decode($value) as such would result in compile time error. Maybe this was all deliberate. This could be a means to enforce privitization of class methods from public usage (POE::Filter::XML::Node::_encode($data) can never succeed), but it feels very klunky. Seems like other Perl techniques would be better suited for private class methods. Nevertheless, in my opinion it is a flaw in the code that's trival to fix and would make the code more usable. Eric
Download (untitled)
application/pgp-signature 189b

Message body not shown because it is not plain text.

PCJ itself will probably also get touched this weekend to expose more of its guts during the whole negotiation/setup process including events that get fired when certain things happen. It has been a short coming that I have wanted to address for awhile now. Punjab (XMLRPC-to-Jabber) makes use of PCJ and a couple of ajax-y webapps make use of Punjab, and there really is no way to get current connection state information from PCJ to Punjab to webapp so you can't even have a progress bar. PCJ also is a very complex monolithic monster. All of the Client classes need to be refactored into a single class and various methods and pieces should be pushed out into subclasses to cut down the amount of copy paste (sigh) that needs to be done when there are changes. POE doesn't make subclassing very easy, and the whole object states thing feels ugly. Ideally, I would like to rewrite PCJ. I would love to see your modifications and see how they fit into my idea on how things should look. Anyhow, addressing your empty prototype comments, yes, it was a means of privitization and deliberate. Klunky is certainly one way of describing it, but at the time, it just worked (and still does ;). And yes, encode/decode were positioned so it would work internally, heh. There are a plethora of techniques for putting locks on the kitchen doors including inside out objects and what not, but they still don't really solve the problem, but add a layer of complexity. If you really really still wanted to invade the kitchen space of an inside out object, you still can. Could you go in and remove all of those empty prototypes? Sure. Then you could pass around the object and arguments into the subs and things would still work. But if the intention was to have an OO developed class to have subs executed in an OO method context, why allow that kind of usage? It is a little hack, I will give you that. And to be honest with you too, some of that code in there has seen its share of bitrot. Originally the _encode()/_decode() mechanism came from DJ Adams Jabber code. It really should be done with an eye more toward XML compliance rather than "what is the minimum I need to do to make sure XML parsers don't barf." That is something I intend to explore this weekend some. As for more usable, it might make sense to revisit the Utils package and move the _encode()/_decode() out there. There are probably some more little things like that should populate that package, too. On Fri Oct 20 11:59:14 2006, ewaters@uarc.com wrote: Show quoted text
> Before I report another bug I'd like to say that I appreciate the work > you've done on this software. I use this and a heavily modified > POE::Component::Jabber (I'll show you the modifications at a later > date) in an app I've been working on for the last few months. > > This bug applies to almost all the code you write. It appears that a > style decision that you made (probably a long time ago) now causes > compile-time errors in Perl v5.8.8 (and earlier versions, not sure > how far back). > > It's also possible that this is a deliberate choice of yours. > > The problem is that every subroutine you write has an empty prototype: > > sub get_id() > { > my $self = shift; > > return $self->[+id]; > } > > Normally this isn't an issue, as you call your subroutines as methods > ($node->get_id()), and according to perlsub, method calls are not > influenced by prototypes. But if you called it as a subroutine (so > prototypes can be checked at compile time), you'd get a compiletime > error: > > #!/usr/bin/perl > > use strict; > use warnings; > > sub increment() > { > my $x = shift; > > return $x + 1; > } > > my $number = increment(5); > print "Have number $number\n"; > > Results in: > > Too many arguments for main::increment at ./prototype_test.pl line > 13, near "5)" > Execution of ./prototype_test.pl aborted due to compilation > errors. > > If the only way you ever called these subroutines was as class > methods, then this would never come up (the empty prototype would > never be evaluated). You seem to have avoided this in the example > of POE::Filter::XML::Node.pm by declaring data() (which calls > _encode() and _decode()) before _encode() and _decode() (since the > subroutines occur after their usage, they can't be checked at > compile time), this means that no function below _decode() can use > _decode($value) as such would result in compile time error. > > Maybe this was all deliberate. This could be a means to enforce > privitization of class methods from public usage > (POE::Filter::XML::Node::_encode($data) can never succeed), but it > feels very klunky. Seems like other Perl techniques would be > better suited for private class methods. > > Nevertheless, in my opinion it is a flaw in the code that's trival to > fix and would make the code more usable. > > Eric