One of my favourite 'tricks'1 is the possibility of putting code in @INC, as explained in [doc://require|perldoc -f require]. Now, the standard way to use it is to return an open filehandle to the wanted module, e.g.
#!/usr/bin/perl
use strict;
use warnings;
use lib sub {
my $wanted=pop;
return undef if $wanted ne 'Foo.pm';
open my $fh, '<', \<<'.EOM' or die "D'Oh! $!\n";
# ---- Begin package code.
use strict;
use warnings;
package Foo;
use base 'Exporter';
our @EXPORT='bar';
sub bar {
print "Hmmm, seems to work!!\n";
}
1;
__END__
.EOM
# ---- End package code.
$fh;
};
use Foo;
bar;
__END__
(Although in this form looks more like obfuscation than a Good Thing™ ;-)
Now, it occurred to me that even if, as usual, there are many other ways to do what I'm about to propose, one may want to use this feature to "alias" a package (or better, a set of packages at a time) by modifying $_[1] (in the case of the sub or array form of this 'trick') - and returning undef to let the default mechanism continue the search in the standard locations. But this is not currently possible:
$ perl -le 'use lib sub {$_[1]="Foo.pm"; undef}; use Anything;'
Modification of a read-only value attempted at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
So I wonder if $_[1] could be made not read-only instead.
I understand that there may be inherent risks in doing so, but
1 See e.g.:
Try this:
@_ = ( $_[0], "Whatever.pm" );PS, if you change the value from read-only, you'll probably be modifying the optree. That's usually a bad idea.
⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊
I'm not sure if I understand your proposal, which is probable, given your hacking skills. However I don't want to force $_[1] to hold "Whatever.pm" for use in the same sub - I want it to be modified as a side-effect of the sub having been called, and I don't want to change the value from read-only either: I "want" it not to be read-only in the first place.
I was thinking of something along these lines: suppose that one writes some modules in different versions for some different OSen (OK: as I premised since the beginning, I know there are other ways to do this), well if she had this feature available then she may do something like:
use lib sub {
for (qw/Foo.pm Bar.pm Baz.pm/) {
if ($_[1] eq $_) {
$_[1] =~ s/\./-$^O./;
last;
}
}
# let perl go on searching the 'faked' .pm!
undef;
};
(There are probably better examples.)
I admit that this opens an ambiguity as to what should be shown in case the modified module can't be found: is it, say, Foo.pm or Foo-linux.pm that can't be found? Probably, both, I would say: the error message may report both the original name and the "current" (at failure time) one, if they differ.
Gawds. Use some mundane fucking magic for once. This @INC hackery sucks when used for things like this. Instead of "crecent wrench" you're pulling out the "hyper-spacial quantum vortex thingie with extra nubbly attachment." I loathe your example.
BEGIN { eval "use Foo-$^O; 1" or die $@; }⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊
I can imagine that someone could come up with a good way to use this feature. For example, in chaining with other code refs. I'm not entirely sure how that would work, but someone might be able to get it to work.
However, I'm pretty sure this particular example would breed nothing but headache and heartache - there is no fallback mechanism here to allow you to say that if Foo-linux.pm doesn't exist, Foo.pm will be fine. Or, if it isn't fine, to print out a usable error message. Because as the user, I'd probably be confused by any error message referencing "Foo-linux.pm" when I had a "use Foo" in my code without some sort of extra information on my screen.
Instead, I would suggest that code that is intended to stack probably should be made into objects that have an INC method (see require). Someone may write a generic "extract from tarball" INC object. If you want to change the name you get from the tarball, you can write your own INC object that wraps the tarball INC object, and changes the name on the way through.
(Note that before looking this up during the writing of this node, I wasn't even aware of INC objects...)
I was aware of the INC object. Well, just because to be sure every now and again I check perldoc -f require, although in fact I usually stick with the "sub form of code-in-@INC". Now, indeed this kind of hackery is there for doing stuff like "extracting from tarball" (or retrieving over a network connection, maybe). In this case, if I "only" want to change a filename, or a relative path (e.g. Foo/*.pm to Foo-devel/*.pm) as shown in my previous example, then I may search regular @INC directories for the real file I want and return an open file handle to it. But that would amount to reinventing the wheel. And it wouldn't chain with other code in @INC. I may just want perl to do that for me instead...
Indeed agree that some care should be payed to a fallback mechanism and to informative error messages. But modulo these caveats, after all this is a somewhat advanced hackery and fundamentally adding the feature would amount to... removing a feature, precisely the one that makes the passed path read-only, so...
Now I have to watch out for code cowboys screwing things up with wierd @INC modifiers, on top of all the other dirty tricks they like to pull with ties and closures and evals, hidden like rats in their 1000 line subroutines. :-(
Life sucks.
--
Ytrew
(ties and closures and evals, oh my!)
I don't. I usually try to write code that's clear, simple, obvious, and provably correct.
I do, however, have to maintain code written by other people. The more wierd corners the language has, the more places for them to hide bugs on me! Sure, you shouldn't hide code in @INC without a good reason, but that's no reason to assume people won't. Remember, many coders adopt worst practices for job security. Unfortunately, the messes they leave behind last years after they're gone.
The bottom line is, for every new feature you add to the language, that's just one more thing I have to check for when I'm debugging to see why someone else's program just broke. Before, I had to make sure @INC had the right module; now I have to verify that some weasly twit hasn't snuck some code in there for no good reason; and made my bugfix fail because of it!
I mentioned ties, closures, and evals not because they're bad when used wisely, but because they're miserable to deal with when badly applied. Which they are. Repeatedly and frequently badly applied. :-(
--
Ytrew
The more wierd corners the language has, the more places for them to hide bugs on me!
I believe you meant to say "The more complex the code my predecessor wrote, the more places he or she may have hid bugs." Otherwise, it seems as if you've subverted your argument about language features badly applied. I can easily imagine a very simple language where it's still possible to write unmaintainable code.
That's just ingy. Most people produce code saner than that.
⠤⠤ ⠙⠊⠕⠞⠁⠇⠑⠧⠊
That's a very good point. Perl 5 does have more than a few unhygenic corners.
(I was under the impression that Catalyst's biggest problem is multiple inheritance. What do you mean plugin method names collide? Who could possibly have seen that coming...)
Assembly language is horrible to maintain, because it's easy to make code self-modifying. I debugged self-modifying System 370 assembly language on my second co-op term; it took a day to guess what the code was trying to do, and almost a month to prove that it was doing what it should. Most of the program was dead code; but in one case, the program modified itself to reach otherwise unreachable code. I spent those extra 29 days searching for a another way the program might reach the rest of the "unreachable" code; but it didn't actually exist. The code was just dead code; leftover and unused. 29 days wasted because of sloppy code maintence, and a performance hack!
Perl is better than Assembly; but there's still great room for improvement. Productivity tools like perltidy don't work as well as they might, because perl is just so complex, exception riddled, and inconsistant. That's a shame, because it didn't need to be like that. It's bad when you can't be sure the tool you're running to format whitespace didn't mis-parse your program and introduce new bugs. I don't know anything else about Python, but I know you can't fail to indent code and have it run in production. Language design does matter!
A simpler, cleaner language requires that the malicious programmer work harder to accomplish the same obfuscations in the same amount of time, and that's a win for me. At some point, they do get fired...
--
Ytrew
A simpler, cleaner language requires that the malicious programmer work harder to accomplish the same obfuscations in the same amount of time...
Oh, please!
Have you truly never seen a program with incomprehensible variable names, entangled control flow, and no particular subdivision into separate functional units? Heck, I could write terrible awful nearly obfuscated code in both Pascal and Scheme by ignoring what hard-earned experience has taught me about writing good code.
In my understanding, what is really scaring the OP is that someone can write apparently innocent code and make a mess that's hard to spot. Probably, some kind of code analysers (or some "flagging" feature inside perl itself, with the lower "p", who knows?) could help to spot if some program uses these "gray" features, and a company could enforce that these should not be used.
Something along these lines (but I really don't know if it's doable) would allow a company decide the "level of cleverness" allowed, while letting the whole Perl community benefit from Perl's un-orthogonality (which I truly love).
Flavio
perl -ple'$_=reverse' <<
It's the extra cleverness on top of all that bad practice is what's killing me. There's only so much I can handle at once.
I can break programs into functional units. I can rename variables. I can detangle control flow with some difficulty. I can refactor chunks and figure out what they do, and even tie them back to the (mostly fogotten) business logic in some cases.
But when I have to examine each and every variable to see if it's tied to something stupid -- that's a perl feature I'd just as soon live without.
When it's hard to clean up whitespace and know it's reformatted correctly -- that's a limitation of the language I could do without. I want those kinds of tools, and I want them to be reliable!
Now I have to scan @INC each time, to see if something wierd is being done to the normal process of loading modules, something that is already error prone enough.
It's not just one thing; it's a whole bunch of straws that add up to a crushed camel handler. All the things to check for add up; I can't read variable assignments without checking for ties, I can't read function calls without checking for parameters being modified, I can't read anything without having to be suspicious of everything, and there's so much that's possible in perl! And every possible avenue is a chance for something to go horribly wrong.
Perl started out as a big, inconsistent language. It's been getting bigger all the time -- the rules for what some idiot can do to screw you up change with each major release of perl. It's hard dealing with all the wierd corner cases, trying to guess what strange side effects might be snuck in with an innocent looking line of code. I just get tired (and whiny, I guess) when someone adds yet another feature to the language that I have to learn just so I can track all the abuses of it.
You know, I'll probably never use that wierd @INC trick; but I still need to know it to stop others from abusing it. Which is what prompted this rant; the more people add to perl, the more work I have to do. Which makes me grumpy.
--
Ytrew
Well, I wouldn't put ties and closures on the same level as evals, especially if you mean string-eval.
Said this, Perl's nature is intrinsically that of a polymorphic, complex, dynamic language with a rich syntax and semantic. You have to live with that! And generally Perl aficionados do like it too! Or else you may try to choose a simpler alternative. (Pssst! Don't tell anyone, but I think that io is very cool - if only I had some spare time I'd like to learn something more about it1)
1 Of course the fact that it has a simple, consistent syntax, and that it has no keywords doesn't automatically make you an expert programmer...
They're all potentially evil. Try working with code like this. What does it do?
$x = $h { foo($y) };
$z = &$x( $a );
eval $z if ( $b );
I don't even know; and I invented this example. :-)
Note that for large hashes and complex, 1000 line functions with obscure return values, you won't really know what that code actually does; it's very hard to figure out what's going on, until runtime (and sometimes not even then -- we've got a special abstraction layer that re-implements a turing machine in software. Don't ask! And the system's too slow! Gof figure!). Welcome to my world. :-(
Note also that if $h is a tied hash, it can change the values of $a and $b. Heck, it could even change the meaning of the code to be evaluated in $z.
Perl's nature is intrinsically that of a polymorphic, complex, dynamic language with a rich syntax and semantic.
It's been growing every more complex every year for the last ten years; and I felt had too much unnecessary complexity back in 1996. Expanding the language rather than cleaning it up and simplifying the messy parts hardly seems a winning propositon to me. It feels like we've been doing a nosedive in wrong direction... and I worried that Perl 6 is mostly cool new features, without concern for how they'll be (mis)used.
You have to live with that!
Maybe, but I don't have to like it. :-( And it takes a massive amount of lobbying effort to get management to change languages, so I'm probably stuck with Perl; a fringe language like Io will need greater support (and much better documentation) before I'll be allowed to code in it/learn it.
--
Ytrew
Try working with code like this. What does it do?
It calls foo with the argument $x to get something which when stringified will give us a codref from a hash. That coderef is then called with an argument $a and is presumably expected to return a codefragment of some sort. We then eval the code frament but only if $b is true.
What it does is pretty clear. Why it is doing what its doing is not clear. But thats to be expected of a three line fragment with useless variable names.
I don't see the point you are making. Although I can see how coderefs in @INC could be a pain to debug.
You know the how: the scaffolding that will set up the coderefs and the eval.
You don't know the what: the important details about what coderef will be executed, which string will be evaled, nor what that code will really *do*. And that can be hard to find out. Tied variables mean that any statement involving variables could do absolutely anything unless I go back to the variable definition (often thousands of lines away), and find out if it's tied, and what it's tied to. Coderefs mean I don't get to know the name of the function being called. Evals mean that the code to be run can be hidden in a string built up entirely at run time.
Maybe I'm just old fashioned, but I'd rather just see simple function calls with a few simple if statements. If I at least had that, I'd at least have the call tree as a framework for debugging: as it is, any function of in one of many, many modules might be called; none of the functions might be called (all dead code, with live code invented at runtime), and it will take a lot of investigation to find out the truth. At least with a call stack, I can just walk down the stack to find out what does what to what, and start making my guesses as to why.
And, you're right; you also don't know why the code does what it does, nor if it is correct behaviour. That's an additional concern, and a serious one; but not knowing what the code does in the first place makes trying to analyze for correctness hard.
*shrug* I don't know if I've made my point clearer, but at least I tried.
--
Ytrew
ied variables mean that any statement involving variables could do absolutely anything unless I go back to the variable definition (often thousands of lines away), and find out if it's tied, and what it's tied to. Coderefs mean I don't get to know the name of the function being called. Evals mean that the code to be run can be hidden in a string built up entirely at run time.
I get where you are coming from, but this time I can't say I agree with you.
When reading a piece of code that uses tied variables, I see little difference between not knowing immediately exactly how the value returned is derived and not knowing immediately how the value returned from a subroutine or method is derived. Okay, the name of the subroutine/method may give you some clue, but equally, so should the name of the tied variable. In either case, the name may be spot on or a complete misnomer.
As for knowing whether the variable is tied or not and the possibility that the declarations "often thousands of lines away". With Perl's ability to locally scope stuff, if that is the case, fire the programmer. For subs and methods, the actual code could be thousands of lines away; in a different module; in a different language.
Perhaps the biggest difference between the two is that with the tied var, you get to name it in a way that makes sense in the context in which it is used, where as subroutines/method names are decided entirely by the writer of the module providing them, and will therefore tend to be generic names that makes sense in terms of what the module does generically, rather than in terms of how you are using it locally.
Coderefs (otherwise known as 'High Order' &| First Class functions) are (IMO, but also in the opinion of a lot of other people too), are the greatest innovation in programming since the word "structured" got tagged in front. Again, with suitable naming, there should be little mystery what the code behind a coderef is doing. And again, the name can be chosen to make sense in terms of the local context rather than some far off genericity. And if scoping is done properly, you shouldn't have far to backtrack to find out where the actual code lives or is generated.
String eval is somewhat different as reflected by the condemnation it receives when people use it unnecessarily, but there are some times when it is the expedient choice. On those occasions, using reasonable variable names (not $x $y and definitely not $a $b), goes a long way to illumination the purpose of the code.
Perhaps the biggest problem with string eval is that the text that shows up in stack traces (eg. Died at (eval 14) line 1 is less than useful in tracking down where in the body of code the eval statement resides. However, on those rare occasions when string eval is useful, there are ways of providing for better information, and given the rarity, it's quite worth the extra effort.
Maybe I'm just old fashioned, but I'd rather just see simple function calls with a few simple if statements.
But then that would not be Perl. It would be a subset of Perl almost certainly guaranteed not to make use of its expressive power. You may also program in the particular language that subset maps into, for what it's worth. Of course this doesn't scale well with the fact that you may have to program in Perl. I can't comment on that... except that if you applied for a a job as a Perl programmer you should be supposed to be familiar with the language and its peculiarities including alas! its corner cases and duouble-alas! misuses.
Don't misunderstand me: this not to say that your fears and concerns expressed in such a colorful manner above are fantasies of yours. I can understand them quite well, however not only -as chromatic correctly remarked- you can "write terrible awful nearly obfuscated code" in less feature-rich languages too, but you can write perfectly clean an maintainable code in a feature-rich language as well; even exploiting those (tricky) features you are scared by. In other words these are mostly orthogonal concepts!
Now your claims fundamentally amount to the belief that there's an implication between feature-richness and tendency to write "bad" code. Of course such a cause-effect relationship does exist, but although it is difficult to quantify this kind of things, my judgment, and the common perception here, are that it is of a much much smaller entity than you seem to think.
Actually, in my experience, bad code I had to deal with was not bad because of the (ab)use of "advanced" features. It was bad because of "basic" shortcomings, e.g. no use of strict and warnings, unchecked opens and so on.
In particular "bad" code -in my acceptation- indeed often features string evals, always in situations in which it is not needed by any means. And I can understand your concerns with tied, variables, although variables do not tie themselves on their own. But I still can't understand what scares you in closures. Care to give an example?
A technical writer doesn't set out to make use of all the "expressive power" of the English language; (s)he seeks clarity and aims to be understood by his/her target audience. So, too, a programmer should aim for clarity, and only write what will be understood. In both cases, using simple language wherever possible is going to make life easier for the person trying to understand later on.
Now your claims fundamentally amount to the belief that there's an implication between feature-richness and tendency to write "bad" code. Of course such a cause-effect relationship does exist, but although it is difficult to quantify this kind of things, my judgment, and the common perception here, are that it is of a much much smaller entity than you seem to think.
I can only speak for my own experiences; but they've been almost uniformly bad. It's not just that feature-richness provides a tendancy to write bad code; it's the general fact that giving someone more than they need becomes awkward. Look at the tendancy for long cords to become tangled; it's the same principle with coding -- more is not better. In both cases, the snarls and tangles don't have to happen: but they do happen on a regular basis.
Actually, in my experience, bad code I had to deal with was not bad because of the (ab)use of "advanced" features. It was bad because of "basic" shortcomings, e.g. no use of strict and warnings, unchecked opens and so on.
Those are very annoying problems to solve; but not hard ones. Depending on the needs of the program, you might, for example, replace all uses of open() with a version with exception handling of some sort (dies, warns, throws an exception object).
The problems I'm facing deal more with the fact that the code itself tells me almost nothing about what the code does; it's all run time decisions that are hidden by as many layers of abstraction as possible. Checks for things that can't happen are layered in with things that can and must be checked; and the run time state has become a total maze of objects, global flags, internal stacks, and code hidden in code references and closures.
In particular "bad" code -in my acceptation- indeed often features string evals, always in situations in which it is not needed by any means. And I can understand your concerns with tied, variables, although variables do not tie themselves on their own. But I still can't understand what scares you in closures. Care to give an example?
Well, closures are coderefs, and that means guessing *which* code a variable currently refers to. Add to that the burden of figuring out the scoping of the closure, and you've got much more cognitive burden than tracing a simple function call. Unless there's no reasonable way around it, I much prefer the simple and obvious solution.
And of course, all of my complaints are interrelated. It's not just closures in and of themselves; it not just the ties, it's not even just the evals (though they really suck!). It's the fact that I'm dealing with codrefs (and occasionally closures) that are generated at run-time by evals with class names being returned by objects that are determined by hash lookups to tied variables that are eventually tied to something or other using hash lookups and evals; a very simplified version of the main loop runs something like this:
while ( @list ) {
$x = shift(@list);
($a,$b) = @$x;
if ( ref($a) eq "CODE" ) {
&$a($b); # modifies @list
} else {
$a->$b; # $a may be a class or an object;
# modifies @list
}
} # end of evil code that tells me nothing
As you can tell, the main section of the code does nothing other than provide some run-time scaffolding to obscure what's going on. The closures and coderefs, the object syntax, the ties, the evals: they all combine to make something hard to understand practically impossible to understand. Any one of them by themselves would be bad enough (especially eval), but together they make it all just horrible.
I'm gaining very little personal benefit from most of Perl's advanced or interesting features, because I need to write Perl that's accessible to a beginner perspective wherever practical to do so. So far, it's been practical to do so, with exactly one exception in two years.[1] On the other hand, every time there's a new feature added to perl, there's one more feature I have to remember to watch out for, just in case some idiot has (ab)used it.
--
Ytrew
[1] I once wrote a pair of redefine() and restore() functions that override and restore the definition of a function at run time. I use it to simplify testing, by doing separate unit testing of parent functions from their child functions. (ie. If the children return a given value, does the parent function correctly?).
I carefully separated the potentially confusing code out into it's own module, documented the functions and their intended purpose, and documented the codebase as well.
A technical writer doesn't set out to make use of all the "expressive power" of the English language; (s)he seeks clarity and aims to be understood by his/her target audience. So, too, a programmer should aim for clarity, and only write what will be understood. In both cases, using simple language wherever possible is going to make life easier for the person trying to understand later on.
Granted. I'm not claiming that programming must be an exercise targeted at making use of all the expressive power of a language. I think that one should use all the support that the language of choice has to offer in terms of expressive power to gain clarity.
I think we both agree that a programmer should "only write what will be understood", the difference being that you mean "by someone who has only a minimal knowledge of the language", whereas I mean "by someone who is reasonably confident with the language".
You can see yourself that your English prose while probably not being the most sophisticated, is definitely not aimed at, say, a baby. Indeed it does make use of quite a lot of English's expressive power. Why should it be different for programming languages? I don't expect the programmer who is to take up my work to be, say, Abigail but I don't want him/her to be a complete newbie either. (S)he must be able to parse the reasonably "complex" constructs I may want to use to attain clarity.
Well, closures are coderefs, and that means guessing *which* code a variable currently refers to. Add to that the burden of figuring out the scoping of the closure, and you've got much more cognitive burden than tracing a simple function call. Unless there's no reasonable way around it, I much prefer the simple and obvious solution.
Letting aside that closures are not necessarily coderefs (who told you that?) and that a coderef needs not necessarily be stored in a variable, if so, then -especially if variables are given sensible names, which is what one should do in any case- it shouldn't be more difficult to find the actual code than with a "regular" sub. If a sub(ref) is a closure around some lexical that's not as closely scoped as possible, and possibly even hard to trace, then it's just a bad use of a closure, exactly like an unchecked use of an open is a bad use of it. It's not that closures are bad, just like opens are not bad, a priori.
You're also talking about "the simple and obvious solution", disregarding the fact that a solution in terms of a closure may be the logically simplest and most obvious one. Personally I find that in many cases such a solution provides the maximum clarity and the right level of encapsulation.
And of course, all of my complaints are interrelated. It's not just closures in and of themselves; it not just the ties, it's not even just the evals (though they really suck!). It's the fact that I'm dealing with codrefs (and occasionally closures) that are generated at run-time by evals with class names being returned by objects that are determined by hash lookups to tied variables that are eventually tied to something or other using hash lookups and evals; a very simplified version of the main loop runs something like this:
Well, I have already expressed my feeling and POV about this, although you seem to differ and I guess I have no chance to convince you. However I'm stressing the concept once (and only once!) more: I'd just call that bad programming. It's not Perl to blame for offering closures and ties and string evals, it's the programmer who abused them to write bad code who's to blame, period!
More features means more degrees of freedom, and thus an enlarged phase space. This also means that there are corners of it that yield more obfuscation and there are corners of it yielding more clarity. It's up to the programmer to decide where to place his code...
I try to follow the writer's rule: "write for your expected audience"; and you seem to have a more sophisticated expected audience than I do. In my case, most of the programmers in my workplace who will be asked to maintain my code just aren't very experienced with perl. If they can't understand it, they'll just come back and ask me; I'll end up maintaining it myself. By using simpler constructs, I improve the odds that someone besides me will be able to maintain the code.
Letting aside that closures are not necessarily coderefs (who told you that?) and that a coderef needs not necessarily be stored in a variable,
Argh... but in some sense, you're making my point for me. How on earth can I try to teach people who barely speak English how closures work if a native speaker with a university education (me) who reads the man pages constantly can't understand all the nuances? It's not like the man page was very clear on the topic, either. Better not to use something than to abuse it, in my opinion.
if so, then -especially if variables are given sensible names, which is what one should do in any case- it shouldn't be more difficult to find the actual code than with a "regular" sub. How would it be less difficult? There's a deeper burder of proof involved for each call. If I see "foo()", I know that the function foo is called. If I see &$coderef, and I believe $coderef contains a reference to the function foo, I still to find out for sure if that's true; it's one more step for me to investigate. Additionally, since Perl lets me change the definition of foo() at runtime, I have to verify that that hasn't happened. If perl didn't allow me the "freedom" to redefine the codebase at runtime, I wouldn't have to check for someone doing that. The more loose ends rattling around, the greater the odds one will go flying and hit someone. :-)
More features means more degrees of freedom, and thus an enlarged phase space. This also means that there are corners of it that yield more obfuscation and there are corners of it yielding more clarity. It's up to the programmer to decide where to place his code...
But because of the way language elements interact, for every choice that leads to enhanced clarity, you've got many, many other choices that lead to obfuscation. The odds favour code becoming incomprehensible unless the programmer is very careful. You seem to assume all programmers are experts, and follow your notion of good programming practice; this is most decidedly not the case. Most programmers are bad; some are medicore; a few are good. Why not optimize for the common case?
PS: since you "sign" your posts anyway, you're a named anonymonk, thus somewhat a fake one: why don't you register instead? I did, a long time ago -- my registered handle is "Ytrew". But I don't have my password at work, and besides, if I gain 5 more XP, my title will change: and I like being called a "monk". :-)
--
Ytrew
I try to follow the writer's rule: "write for your expected audience"; and you seem to have a more sophisticated expected audience than I do. In my case, most of the programmers in my workplace who will be asked to maintain my code just aren't very experienced with perl. If they can't understand it, they'll just come back and ask me; I'll end up maintaining it myself. By using simpler constructs, I improve the odds that someone besides me will be able to maintain the code.
Maybe spend some of your time bringing your co-workers up to speed? I usually find teaching stuff a more effective use of my time than coding to the lowest common denominator or turning myself into a bottleneck.
Your point is a good one; and if I were in charge of the department, that's what I'd do. On the other hand, I'm not.
1) I'm not a manager; I don't get to decide how to spend my time. Projects get given to me and I do the best I can with them. Training is not really part of my job description; so I'd have to do training for free after hours. I don't mind teaching, but doing it for free after a long day's work, knowing it will benefit my employer more than it will me, doesn't seem all that fair to me.
2) Many of my co-workers don't speak English as a first language; discussing technical concepts is more difficult because of a language barrier. Essentially, at times I end up teaching two languages at once (English+Perl); so progress is frustratingly slow, and, like I said, it's not something I'm supposed to spend much time on.
3) I just don't find it that hard to write simpler code; part of what I was railing at was an ex-coworker using an incredibly obfuscated micro-language solution (with ties, coderefs, objects, evals -- the whole kitchen sink) where a simple SQL query would have sufficed. I find that if I write in a simple, consistant style, I don't have to worry about the alternative ways of "phrasing" something; there's the simple, straightforward encoding, and then there's "something else". If I have to think about something else, odds are I need to think about how to encapsulate the problem better. Nothing I work with is very hard.
Perhaps if I were an engineer working with differential equations, or a statistician analysing stock market trends, or an AI researcher, I'd need some of those exotic features in Perl. But I just don't need that much complexity to automate FTP downloads, or convert file formats, or do simple financial calculations, or to implement other simple business logic. I get no benefit from @INC codrefs, or other wacky perl features. I just have to make sure they're not being used against me. :-(
-
Ytrew
1) I'm not a manager; I don't get to decide how to spend my time. Projects get given to me and I do the best I can with them. Training is not really part of my job description; so I'd have to do training for free after hours. I don't mind teaching, but doing it for free after a long day's work, knowing it will benefit my employer more than it will me, doesn't seem all that fair to me.
I'm certainly not suggesting doing it for for free :-) But it might be worth proposing it to your manager and getting them to pay you to do it instead
perlmonks.org content © perlmonks.org and adrianh, Anonymous Monk, blazar, BrowserUk, chromatic, demerphq, diotalevi, frodo72, perrin, Roy Johnson, sri, Tanktalus, ysth
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03