Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: Mmmm ... cargo cult progamming is nummy!

by Anonymous Monk
on Feb 27, 2002 at 02:41 UTC ( #147799=note: print w/ replies, xml ) Need Help??


in reply to Mmmm ... cargo cult progamming is nummy!
in thread Adding autoloaded methods to symbol table with using strict refs

What that's really doing is co-opting your constructor (typically called new()) and using it as a copy function, (typically called copy() or clone()).
In addition, EVERY single time I've seen ref $proto || $proto written, there was no provision made for a copy constructor.

How do you manage to combine those two statements? Why is there a belief that new as an instance method is a clone method? As you say, it's hardly ever (never?) used as one so why do people think that it is? Is it just paranoia due to that one module once did that? Or that someone just invented that idea? Or is it an idea from some other language?

I too have never seen new being used for anything else than a constructor. Or perhaps I have, but it must have been a long time ago if so. Neither have I ever even thought about incorporating a clone functionality into new. But I can understand the objections to using it if many people manage interpret $bar = $foo->new as $bar = $foo->clone.

I also believe that this interpretation is not very probable if new has any arguments. Then you'd typically see that it's not a clone method. $other_dog = $dog->new($name) can hardly be confused as a clone operation, or can it?

Just for fun I wrote a script that (tries to) find usages of $class = ref $proto || $proto or similar constructs. I ran it on all my installed Perl modules. I found quite a few. I rehacked the program to find usages of $obj->new; or similar. I found... none. Perhaps it's not terrific to make this search on these modules, since many of the installed modules doesn't use other objects, so let's not draw hasted conclusions. But perhaps it gives a pointer.

I'm not sure I'll stop using $proto though. It's already a wide-spread style and some people like it. To stop using it would be to enforce a style upon another. It's not an either-or situation. Those that like to use $obj->new can continue if they feel like it. Those that prefer ref($obj)->new can do that as well. As for the confusion argument: if people get confused by seeing $class = ref $proto || $proto they're probably not too familiar with the Perl culture. If they get confused by $other_dog = $dog->new then I'd say the same: this is not common Perl practice and isn't to be expected. The "make a new object with the same class as this object" interpretation is the common interpretation.

The one thing I might "enforce" or at least encourage through providing this usage is that the maintainer should have a fair share of knowledge about the common Perl practices. That I really do want to enforce. (Of course, this argument stands and falls on that new indeed never is being used a clone method -- something I have no reason to doubt in this moment.)

-Anomo


Comment on Re: Mmmm ... cargo cult progamming is nummy!
Select or Download Code
Re: Re: Mmmm ... cargo cult progamming is nummy!
by chromatic (Archbishop) on Feb 27, 2002 at 05:05 UTC
    I'm not in favor of adding unused code to my program just because other people may be used to it. I'm also opposed to adding half of a feature, especially if it doesn't work. Why muddy the intent of the code for no benefit?

    Of all the people I've seen using this construct, only one could explain what it does. I'm leery of taking advice from people who don't know what they're doing or why it might be done.

    I'm also unrepentently preaching a style. "Write only what you need."

Re2: Mmmm ... cargo cult progamming is nummy!
by dragonchild (Archbishop) on Feb 27, 2002 at 14:24 UTC
    As for the confusion argument: if people get confused by seeing my $class = ref $proto || $proto they're probably not too familiar with the Perl culture.

    The people complaining about this construction are familiar with "Perl culture." Heck, it's arguable that merlyn helped create some of that "Perl culture"! In my experience, the people who use this construction are the very people who are inexperienced with Perl culture. To call this part of Perl culture is to say that inefficient coding is part of Perl culture. That is something I will not accept.

    You also seemed to be confused by a programming-theory concept. A copy constructor is a constructor that is invoked as an instance method and uses the values of the invoking instance as the default values for the new instance. Any values passed in to the constructor override the values of the invoking instance. Hence, the line

    my $otherDog = $thisDog->new($someParameters);
    creates $otherDog using all the values of $thisDog, save when $someParameters would override those values. A clone() method would do the same thing.

    You also state that you found a large usage of my $class = ref $proto || $proto;, but didn't find any usage of those constructors as copy constructors. You then say that we shouldn't "draw hasted conclusions"sic. I personally think that this data does support a conclusion. If a line of code is a no-op in every instance, then it shouldn't be written. It slows down the code as well as confuses all maintainers of that code. To me, the latter is much more important than the former. Whenever I see my $class = ref $proto || $proto;, I'm looking for this constructor to have use as a copy constructor. When I don't see that, my opinion of the programmer's skill drops. The programmer obviously did not understand why s/he wrote that line.

    As to why that's important ... let's suppose that the line was really $class = ref $proto || $proto; (which doesn't have the my in front of $class). That raises an error under strict. If you didn't understand why the statement was there, you now have a broken module and the line that's breaking it is one you are afraid to fix! That's the problem with cargo-cult programming. It disperses code that is viewed akin to magic by those using it. "If I wave my hands and chant this verse, my code will work." I don't ever want to work with someone who's written code with that mentality. It just means that I have to clean up after them. I hate cleaning.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      The people complaining about this construction are familiar with "Perl culture."

      And how is that related to the people being confused about the construction? The people that are complaining about it (including you) are not confused about it. Or are you saying that you're confused about it? That would indeed explain a lot.

      Heck, it's arguable that merlyn helped create some of that "Perl culture"!

      But that doesn't mean he is the Perl culture. And a culture is a living thing, so who started it is quite irrelevant. By the way, you're not implying that merlyn too is confused about the construction, are you? I hope not.

      To call this part of Perl culture is to say that inefficient coding is part of Perl culture. That is something I will not accept.

      If people in a culture practice it then it's a part of the culture, is it not? I find it quite irrelevant if you can accept it or not. I'm not trying to convince you to accept a certain moral or whatever. You can't say "I won't accept this conclusion just because I dislike it". Well, you can, of course. It's a free forum, but arguments like that have no weight over here. I don't really agree with your logic though. But it's known that there's a lot of poor Perl code out there. If people use $class = ref $proto || $proto without knowing what it does, then I agree -- that is bad. But if they know what they're doing and have a purpose with it then I disagree.

      You also seemed to be confused by a programming-theory concept.

      Yes, I am indeed confused about what copy/clone constructors you talk about. The clone constructors I've seen in Perl use no arguments and just makes a deep-copy (sometimes using Data::Dumper or such), alternatively a shallow-copy. Again I wrote a script that tried to find copy/clone methods. I found a few and none of them used any arguments.

      You also state that you found a large usage of my $class = ref $proto || $proto;, but didn't find any usage of those constructors as copy constructors. [snip] I personally think that this data does support a conclusion.

      I think that the code I used it for was more suited to show that many modules use that construction, than to prove it's not used. Most of the modules that were looked at do not use other modules. So naturally you won't find any $obj->new invocations. But you will find a lot of constructors, and it's in the constructors that you'll find $class = ref $proto || $proto. The material is full of constructors, but few non-self method invocations. This is why I think it's not a good source to prove your point.

      If a line of code is a no-op in every instance, then it shouldn't be written.

      You're still assuming that people aren't using $obj->new as a short-cut for ref($obj)->new. I'm not as sure of that as you are. And I know in fact that some people like it. I'm not sure they use it though. However, my argumentation is based on that at least some people use it. If you don't agree with that please just state so. But if your trying to make contra arguments please to it in the frame that we're discussing.

      Whenever I see my $class = ref $proto || $proto;, I'm looking for this constructor to have use as a copy constructor.

      Again I ask why? You just agreed that this particular construction is hardly ever used for copy constructors. Then why do you think it is one? Why do you expect it if you never encounter it? This seems like "cargo-cult thinking". You think it just because... well, just because! At least I assume you do, because you didn't give an explanation.

      let's suppose that the line was really $class = ref $proto || $proto; (which doesn't have the my in front of $class). That raises an error under strict.

      Oh, so if we don't use this construct we'll get rid of the strict problem? That's really amazing. (Or in other words, why the heck do you bring up this? It's not even remotely related.)

      I've tried to do a couple of reality checks (not perfect, but yet enough to get an indication) to get this discussion down from theory to reality. So let's try to face the reality or at least try to find something that indicates that my checks were flawed in some way.

      -Anomo

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://147799]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (9)
As of 2014-09-22 08:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (185 votes), past polls