Re: ARGH!
# from Jonathan Rockway # on Thursday 19 February 2009 11:20: * On Thu, Feb 19 2009, Ovid wrote: The module in question should provide a sub or method to provide access to this data. This is a good point. Java programmers learned long ago not to let people touch their privates, Perl programmers should learn the same thing. That's the wrong way to look at it. The way to be civil is not to focus on protecting *your* privates, but to have a culture where people don't just go around grabbing things they're not supposed to. The only thing *one* can do is to refrain from the undesirable behavior with the understanding that others will do the same. This is one of Java's worst design decisions. This may be true. Still, providing accessors and mutators encourages them to be used and provides a contract where you won't break things if they're used properly. In most places where I've seen private attributes which were private due to necessity, the issue is actually that there's some assumption being made about the data with regard to a procedure which spans multiple method calls or the life of the object. If they're being made private for safety/paranoia/laziness, that's just a design error or lack of foresight or lack of features or whatever. Either way, debating the maintenance hassle of forking vs the maintenance hassle of work-arounds or monkey patches seems to miss the point that the problem is a library with the wrong abstraction. Is there a critic metric for that? --Eric -- But as to modern architecture, let us drop it and let us take modernistic out and shoot it at sunrise. --F.L. Wright --- http://scratchcomputing.com ---
Re: ARGH!
On Feb 21, 2009, at 2:10 AM, Eric Wilhelm wrote: Is there a critic metric for that? There are several designed to protect internals. Here are the ones among the Perl::Critic core policies: Subroutines::ProtectPrivateSubs ValuesAndExpressions::ProhibitLongChainsOfMethodCalls Variables::ProtectPrivateVars Variables::ProhibitPackageVars Chris
Re: ARGH!
* Jonathan Rockway j...@jrock.us [2009-02-19 20:20]: In general, whenever Java does something, you actually want the opposite. The Perl way is no better. What you really want is to make sure that people can get at innards if they are deliberately trying to, but will stay off each others’ toes as long as they’re doing their own thing. Java overdoes it by going to one extreme, Perl by going to the other. Or at least the naïve Perl approaches overdo it. It wouldn’t be Perl if you couldn’t fix it, and you can by using package scalars to store private methods and package hashes to store inside-out object fields. That way, things actually get namespaced, so you don’t have to check all your sub- and superclasses to make sure your private methods and instance fields don’t override or clash with (respectively) theirs. A great bonus is that while messing around in an object’s internals outside your own package is easy to do, there’s some pretty repulsive syntactic salt associated with it – as it should be. Regards, -- Aristotle Pagaltzis // http://plasmasturm.org/
Re: ARGH!
* On Fri, Feb 20 2009, Aristotle Pagaltzis wrote: A great bonus is that while messing around in an object’s internals outside your own package is easy to do, there’s some pretty repulsive syntactic salt associated with it – as it should be. A great bonus? Easy things should be easy. You shouldn't need syntactic salt to prevent yourself from writing bad code. You should avoid writing bad code because it's bad. I could go on and on about why inside out objects are worthless, but it's not worth the effort. Anyone that cares already knows :) Fortunately, it's easy to remove all that brain damage anyway: http://search.cpan.org/~swalters/Acme-RightSideOutObject-0.01/lib/Acme/RightSideOutObject.pm Regards, Jonathan Rockway -- print just = another = perl = hacker = if $,=$
Re: ARGH!
* Jonathan Rockway j...@jrock.us [2009-02-20 21:15]: A great bonus? Easy things should be easy. Typing out a fully qualified package name is difficult? Huh. You shouldn't need syntactic salt to prevent yourself from writing bad code. You should avoid writing bad code because it's bad. Have you heard a talk by this guy, Larry Wall? He often talks about linguistic principles in language design. You should listen to him, he has interesting things to say. I could go on and on about why inside out objects are worthless, but it's not worth the effort. Anyone that cares already knows :) Gee. Well I never thought of it like that… you have totally convinced me! Nitpicking aside, I note that you have not lost a single word about the central argument of my mail that Perl does not make it easy enough to stay off everyone else’s toes when you aren’t explicitly looking to mess with their privates. Let me guess – it’s not worth the effort, right? If I cared, I would already know… Regards, -- Aristotle Pagaltzis // http://plasmasturm.org/
Re: ARGH! (was FW: Perl Critic and (honest) hash references)
Ovid wrote: Readonly constants are just easier to use and have fewer gotchas. they have indeed, when you need to access the constants from outside of the module they are declared in (which is a pretty common case). cfr. Foo::Bar::CONSTANT_FIELD vs. $Foo::Bar::CONSTANT_FEILD. the latter fools strict. IMHO, the unconditional sponsoring of Readonly by PBP is just plain wrong. cheers, Aldo
Re: ARGH! (was FW: Perl Critic and (honest) hash references)
- Original Message From: Aldo Calpini d...@perl.it Ovid wrote: Readonly constants are just easier to use and have fewer gotchas. they have indeed, when you need to access the constants from outside of the module they are declared in (which is a pretty common case). It also used to be very common not to use strict or warnings. This doesn't mean it's a good thing. The module in question should provide a sub or method to provide access to this data. Java programmers learned long ago not to let people tough their privates, Perl programmers should learn the same thing. (For example, when the constant is computed rather than declared, wrapping it in a sub saves a *lot* of grief -- if you've done that up front and not forced people to change their APIs). If you *must* use globals, it's certainly a good thing that they're read-only but at the very least, do it sanely: package Some::Module; use Readonly; Readonly our $foo = 3; use Exporter 'import' our @EXPORT_OK = ('$foo'): Note that we've been forced to switch from 'my' to 'our' in the Readonly variable, but now the calling code doesn't need a fully-qualified package name: use Some::Module '$foo'; print $foo; Cheers, Ovid -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Tech blog- http://use.perl.org/~Ovid/journal/ Twitter - http://twitter.com/OvidPerl Official Perl 6 Wiki - http://www.perlfoundation.org/perl6
Re: ARGH! (was FW: Perl Critic and (honest) hash references)
On Thu, Feb 19, 2009 at 09:04:35AM +0100, Aldo Calpini wrote: IMHO, the unconditional sponsoring of Readonly by PBP is just plain wrong. An awful lot of PBP is Just Plain Wrong if you treat it as hard-and- fast rules that should be obeyed all the time. Thankfully, the book makes it clear that it shouldn't be treated that way. -- David Cantrell | http://www.cantrell.org.uk/david engineer: n. one who, regardless of how much effort he puts in to a job, will never satisfy either the suits or the scientists
RE: ARGH! (was FW: Perl Critic and (honest) hash references)
That is primarily due to their special ability to slay powerful beasties. :} Roger -Original Message- From: Aristotle Pagaltzis [mailto:pagalt...@gmx.de] Sent: Thursday, February 19, 2009 10:13 AM To: module-authors@perl.org Subject: Re: ARGH! (was FW: Perl Critic and (honest) hash references) Everyone seems to be looking for silver bullets.
Re: ARGH!
* On Thu, Feb 19 2009, Ovid wrote: Java programmers learned long ago not to let people touch their privates, Perl programmers should learn the same thing. This is one of Java's worst design decisions. A while back, I needed to customize the way URLConnection worked. The parts I needed to touch were private, so I had to copy the source files from the open source java implementation, modify one line, and use my custom library instead of the one bundled with the JVM. All because they said private instead of public, and the runtime insisted on enforcing that restriction. (Sure, they could change the implementation out from under me. I am willing to take that risk. The point is that it should be *my* decision, not the module author's decision.) In general, you should make it clear that internals are at your own risk, but you shouldn't physically prevent access. It just wastes everyone's time, and doesn't make any code more maintainable. (Since I'll just have to cut-n-paste to work around it.) In general, whenever Java does something, you actually want the opposite. This case is no exception. Regards, Jonathan Rockway -- print just = another = perl = hacker = if $,=$
ARGH! (was FW: Perl Critic and (honest) hash references)
Well foo. I see it now. RTFM is always pretty good advice, eh? :} Roger -Original Message- From: Roger Hall [mailto:raha...@ualr.edu] Sent: Wednesday, February 18, 2009 10:05 AM To: module-authors@perl.org Subject: Perl Critic and (honest) hash references All, I'm a fan of Class::Std and Dr. Conway's efforts, but I'm bemused by a failing perlcritic test on a new module. I used a hash reference to hold several values to make it easier to dump with YAML, so my code is peppered with code like this: $config-{query} Perlcritic complains that Private Member Data shouldn't be accessed directly because Accessing an objects data directly breaks encapsulation and should be avoided. I get that. Only problem: it's not an object. It's just a hashref. Do I have to redesign the module to get past this syntatical doppelganger? Should I just rip the perlcritic test out of my distribution? Any advice appreciated! Thanks! Roger Hall Technical Director MidSouth Bioinformatics Center University of Arkansas at Little Rock (501) 569-8074
ARGH! (was FW: Perl Critic and (honest) hash references)
Well foo. I see it now. RTFM is always pretty good advice, eh? :} Roger -Original Message- From: Roger Hall [mailto:raha...@ualr.edu] Sent: Wednesday, February 18, 2009 10:05 AM To: module-authors@perl.org Subject: Perl Critic and (honest) hash references All, I'm a fan of Class::Std and Dr. Conway's efforts, but I'm bemused by a failing perlcritic test on a new module. I used a hash reference to hold several values to make it easier to dump with YAML, so my code is peppered with code like this: $config-{query} Perlcritic complains that Private Member Data shouldn't be accessed directly because Accessing an objects data directly breaks encapsulation and should be avoided. I get that. Only problem: it's not an object. It's just a hashref. Do I have to redesign the module to get past this syntatical doppelganger? Should I just rip the perlcritic test out of my distribution? Any advice appreciated! Thanks! Roger Hall Technical Director MidSouth Bioinformatics Center University of Arkansas at Little Rock (501) 569-8074
RE: ARGH! (was FW: Perl Critic and (honest) hash references)
Bill, We can exclude specific policies in the code with specially formatted comments. The M in this (RTFM) case is here: http://search.cpan.org/~elliotjs/Perl-Critic-1.096/lib/Perl/Critic.pm#BENDIN G_THE_RULES The specific policies aren't properly linked, but Google knows all: http://search.cpan.org/~elliotjs/Perl-Critic-1.082/lib/Perl/Critic/PolicySum mary.pod I haven't actually figured out which policy to exclude yet though. Roger -Original Message- From: Bill Ward [mailto:b...@wards.net] Sent: Wednesday, February 18, 2009 11:11 AM To: raha...@ualr.edu Subject: Re: ARGH! (was FW: Perl Critic and (honest) hash references) What was the solution? On Wed, Feb 18, 2009 at 8:53 AM, Roger Hall raha...@ualr.edu wrote: RTFM is always pretty good advice, eh? :} -Original Message- From: Roger Hall [mailto:raha...@ualr.edu] Sent: Wednesday, February 18, 2009 10:05 AM To: module-authors@perl.org Subject: Perl Critic and (honest) hash references $config-{query} Perlcritic complains that Private Member Data shouldn't be accessed directly because Accessing an objects data directly breaks encapsulation and should be avoided. I get that. Only problem: it's not an object. It's just a hashref.
RE: ARGH! (was FW: Perl Critic and (honest) hash references)
I had to dig around in the policy modules because it isn't actually listed in the other document I linked. Specifically: ProhibitAccessOfPrivateData I'm only sure this is it because the error message that came out of the report ... Private Member Data shouldn't be accessed directly at line X, column Y. Accessing an objects data directly breaks encapsulation and should be avoided. ... is prominently displayed in the module. Thanks! Roger -Original Message- From: Bill Ward [mailto:b...@wards.net] Sent: Wednesday, February 18, 2009 11:11 AM To: raha...@ualr.edu Subject: Re: ARGH! (was FW: Perl Critic and (honest) hash references) What was the solution? On Wed, Feb 18, 2009 at 8:53 AM, Roger Hall raha...@ualr.edu wrote: RTFM is always pretty good advice, eh? :} -Original Message- From: Roger Hall [mailto:raha...@ualr.edu] Sent: Wednesday, February 18, 2009 10:05 AM To: module-authors@perl.org Subject: Perl Critic and (honest) hash references $config-{query} Perlcritic complains that Private Member Data shouldn't be accessed directly because Accessing an objects data directly breaks encapsulation and should be avoided. I get that. Only problem: it's not an object. It's just a hashref.
Re: ARGH! (was FW: Perl Critic and (honest) hash references)
Hi Roger, How do you perform your perlcritic runs? I can recommend the verbosity setting 8 perlcritic --verbose 8 This gives you quite friendly policy identifiers [ValuesAndExpressions::ProhibitConstantPragma] Pragma constant used at line 22, column 1. (Severity: 4) well my favorite anyway jonasbn On 18/02/2009, at 21.17, Roger Hall wrote: I had to dig around in the policy modules because it isn't actually listed in the other document I linked. Specifically: ProhibitAccessOfPrivateData I'm only sure this is it because the error message that came out of the report ... Private Member Data shouldn't be accessed directly at line X, column Y. Accessing an objects data directly breaks encapsulation and should be avoided. ... is prominently displayed in the module. Thanks! Roger -Original Message- From: Bill Ward [mailto:b...@wards.net] Sent: Wednesday, February 18, 2009 11:11 AM To: raha...@ualr.edu Subject: Re: ARGH! (was FW: Perl Critic and (honest) hash references) What was the solution? On Wed, Feb 18, 2009 at 8:53 AM, Roger Hall raha...@ualr.edu wrote: RTFM is always pretty good advice, eh? :} -Original Message- From: Roger Hall [mailto:raha...@ualr.edu] Sent: Wednesday, February 18, 2009 10:05 AM To: module-authors@perl.org Subject: Perl Critic and (honest) hash references $config-{query} Perlcritic complains that Private Member Data shouldn't be accessed directly because Accessing an objects data directly breaks encapsulation and should be avoided. I get that. Only problem: it's not an object. It's just a hashref.
RE: ARGH! (was FW: Perl Critic and (honest) hash references)
Jonas, Honestly I just left the default perlcritic test script in my package as generated by Module::Starter. This was the first time I had done so, and I really had no idea about Perl::Critic until last night when my module failed smoke testing after upload to CPAN. From the test script I am guessing that I cannot alter the verbosity setting (running on someone else's automated server). #!perl if (!require Test::Perl::Critic) { Test::More::plan( skip_all = Test::Perl::Critic required for testing PBP compliance ); } Test::Perl::Critic::all_critic_ok(); Incidentally, I have tried to install P::C today, but I can't get past PPI (or a dependency). I keep running out of memory (which may be a failing memory stick in my machine, because it has 8 gigs of RAM). Someday maybe I'll try again and kill the test that is sticking: t/14_charsetsok 1/11Out of memory! It is from: ADAMK/PPI-1.203.tar.gz Thanks for the suggestion! Roger -Original Message- From: Jonas Brømsø Nielsen [mailto:jona...@gmail.com] Sent: Wednesday, February 18, 2009 2:23 PM To: raha...@ualr.edu Cc: 'Bill Ward'; module-authors@perl.org Subject: Re: ARGH! (was FW: Perl Critic and (honest) hash references) Hi Roger, How do you perform your perlcritic runs? I can recommend the verbosity setting 8 perlcritic --verbose 8 This gives you quite friendly policy identifiers [ValuesAndExpressions::ProhibitConstantPragma] Pragma constant used at line 22, column 1. (Severity: 4) well my favorite anyway jonasbn On 18/02/2009, at 21.17, Roger Hall wrote: I had to dig around in the policy modules because it isn't actually listed in the other document I linked. Specifically: ProhibitAccessOfPrivateData I'm only sure this is it because the error message that came out of the report ... Private Member Data shouldn't be accessed directly at line X, column Y. Accessing an objects data directly breaks encapsulation and should be avoided. ... is prominently displayed in the module. Thanks! Roger -Original Message- From: Bill Ward [mailto:b...@wards.net] Sent: Wednesday, February 18, 2009 11:11 AM To: raha...@ualr.edu Subject: Re: ARGH! (was FW: Perl Critic and (honest) hash references) What was the solution? On Wed, Feb 18, 2009 at 8:53 AM, Roger Hall raha...@ualr.edu wrote: RTFM is always pretty good advice, eh? :} -Original Message- From: Roger Hall [mailto:raha...@ualr.edu] Sent: Wednesday, February 18, 2009 10:05 AM To: module-authors@perl.org Subject: Perl Critic and (honest) hash references $config-{query} Perlcritic complains that Private Member Data shouldn't be accessed directly because Accessing an objects data directly breaks encapsulation and should be avoided. I get that. Only problem: it's not an object. It's just a hashref.
RE: ARGH! (was FW: Perl Critic and (honest) hash references)
Honestly I just left the default perlcritic test script in my package as generated by Module::Starter. This was the first time I had done so, and I really had no idea about Perl::Critic until last night when my module failed smoke testing after upload to CPAN. From the test script I am guessing that I cannot alter the verbosity setting (running on someone else's automated server). Score one for the good guys: annoying our users into writing better code. ;-) Chris
RE: ARGH! (was FW: Perl Critic and (honest) hash references)
Or at least figuring out how to turn it off! ;} (Actually, I also had a bare file handle and two-arg file open; *that* I changed. So I am proud for the help!) BTW - could you change the smoke settings for perlcritic to verbose as Jonas described? (Or do I misunderstand how the smoke system works?) Roger -Original Message- From: Chris Dolan [mailto:ch...@chrisdolan.net] Sent: Wednesday, February 18, 2009 2:44 PM To: raha...@ualr.edu Cc: 'Jonas Brømsø Nielsen'; module-authors@perl.org Subject: RE: ARGH! (was FW: Perl Critic and (honest) hash references) Honestly I just left the default perlcritic test script in my package as generated by Module::Starter. This was the first time I had done so, and I really had no idea about Perl::Critic until last night when my module failed smoke testing after upload to CPAN. From the test script I am guessing that I cannot alter the verbosity setting (running on someone else's automated server). Score one for the good guys: annoying our users into writing better code. ;-) Chris
Re: ARGH! (was FW: Perl Critic and (honest) hash references)
Still, that's bogus for ordinary hashes... it should only care about that for objects. Though I wonder how it could possibly know the difference. On Wed, Feb 18, 2009 at 12:17 PM, Roger Hall raha...@ualr.edu wrote: I had to dig around in the policy modules because it isn't actually listed in the other document I linked. Specifically: ProhibitAccessOfPrivateData I'm only sure this is it because the error message that came out of the report ... Private Member Data shouldn't be accessed directly at line X, column Y. Accessing an objects data directly breaks encapsulation and should be avoided. ... is prominently displayed in the module. Thanks! Roger -Original Message- From: Bill Ward [mailto:b...@wards.net] Sent: Wednesday, February 18, 2009 11:11 AM To: raha...@ualr.edu Subject: Re: ARGH! (was FW: Perl Critic and (honest) hash references) What was the solution? On Wed, Feb 18, 2009 at 8:53 AM, Roger Hall raha...@ualr.edu wrote: RTFM is always pretty good advice, eh? :} -Original Message- From: Roger Hall [mailto:raha...@ualr.edu] Sent: Wednesday, February 18, 2009 10:05 AM To: module-authors@perl.org Subject: Perl Critic and (honest) hash references $config-{query} Perlcritic complains that Private Member Data shouldn't be accessed directly because Accessing an objects data directly breaks encapsulation and should be avoided. I get that. Only problem: it's not an object. It's just a hashref.
Re: ARGH! (was FW: Perl Critic and (honest) hash references)
On Wed, Feb 18, 2009 at 12:22 PM, Jonas Brømsø Nielsen jona...@gmail.comwrote: Hi Roger, How do you perform your perlcritic runs? I can recommend the verbosity setting 8 perlcritic --verbose 8 This gives you quite friendly policy identifiers [ValuesAndExpressions::ProhibitConstantPragma] Pragma constant used at line 22, column 1. (Severity: 4) What's wrong with 'use constant'?
Re: ARGH! (was FW: Perl Critic and (honest) hash references)
From: Bill Ward b...@wards.net This gives you quite friendly policy identifiers [ValuesAndExpressions::ProhibitConstantPragma] Pragma constant used at line 22, column 1. (Severity: 4) What's wrong with 'use constant'? Well, nothing's wrong with it. It does, however, get clumsy in some cases. For example: use constant FOO = 3; print $data-{+FOO}; print We have @{[FOO]} widgets; # or print We have .FOO. widgets; Versus: use Readonly; Readonly my $FOO = 3; print $data-{$FOO}; print We have $FOO widgets; Readonly constants are just easier to use and have fewer gotchas. Cheers, Ovid -- Buy the book - http://www.oreilly.com/catalog/perlhks/ Tech blog- http://use.perl.org/~Ovid/journal/ Twitter - http://twitter.com/OvidPerl Official Perl 6 Wiki - http://www.perlfoundation.org/perl6
Re: ARGH! (was FW: Perl Critic and (honest) hash references)
On Feb 18, 2009, at 9:08 PM, Bill Ward wrote: Still, that's bogus for ordinary hashes... it should only care about that for objects. Though I wonder how it could possibly know the difference. Can we define an object as a blessed hash reference? And leave unblessed hashes available as little bundles of data? We could distinguish between objects which are 100% encapsulated and records which are 0% encapsulated--just handy slates of public data. 2¢, Ezra
Re: ARGH! (was FW: Perl Critic and (honest) hash references)
On Wed, 18 Feb 2009 22:03 +, Ezra Cooper e...@ezrakilty.net wrote: On Feb 18, 2009, at 9:08 PM, Bill Ward wrote: Still, that's bogus for ordinary hashes... it should only care about that for objects. Though I wonder how it could possibly know the difference. Only by executing the program, I think. It couldn't be a static test. -- Curtis Jewell swords...@csjewell.fastmail.us %DCL-E-MEM-BAD, bad memory -VMS-F-PDGERS, pudding between the ears [I use PC-Alpine, which deliberately does not display colors and pictures in HTML mail] -- Curtis Jewell swords...@csjewell.fastmail.us %DCL-E-MEM-BAD, bad memory -VMS-F-PDGERS, pudding between the ears [I use PC-Alpine, which deliberately does not display colors and pictures in HTML mail]
Re: ARGH! (was FW: Perl Critic and (honest) hash references)
On Wed, Feb 18, 2009 at 3:35 PM, Curtis Jewell perl.module-auth...@csjewell.fastmail.us wrote: On Wed, 18 Feb 2009 22:03 +, Ezra Cooper e...@ezrakilty.net wrote: On Feb 18, 2009, at 9:08 PM, Bill Ward wrote: Still, that's bogus for ordinary hashes... it should only care about that for objects. Though I wonder how it could possibly know the difference. Only by executing the program, I think. It couldn't be a static test. Yeah, I agree. I can see it as a warning, but not as a hard error. I've never used Perl::Critic actually, but we're looking into using it to supplement our existing (homemade) standards compliance checker at work.
Re: ARGH! (was FW: Perl Critic and (honest) hash references)
This was caused by the tester having Perl::Critic::Nits installed, which is not part of core Perl::Critic. Perl::Critic tests should NOT be enabled by default for any CPAN distribution. Do with your P::C test whatever you do with the rest of your author tests to prevent them running by default. As others have said, you can specify the verbosity in a perlcriticrc file. Personally, I use this everywhere: verbose = %f: %m at line %l, column %c. %e. (Severity: %s, %p)\n This includes the short name of the policy (the %p) at the end. You could have blocked this policy and all other non-core policies using the theme option: theme = core But you should still shouldn't allow it to run by default. Let us say that your code is perfect as far as P::C is concerned. Your distribution gets installed on thousands of peoples' machines and all the tests run perfectly on every single one of them. A year goes by and everybody is happy (without you having to change a thing). A new version of Perl::Critic comes out with a new policy which your code doesn't comply with (you evil person, your POD isn't written in Pig Latin!). Suddenly, your code looks bad and no one can install your distribution. You really don't want Perl::Critic being run as part of regular testing in a CPAN distribution. (DarkPAN code is another matter.)