go ahead... be a heretic | |
PerlMonks |
Re^15: $class = ref $class || $class (not me)by tye (Sage) |
on Mar 06, 2003 at 00:14 UTC ( [id://240755]=note: print w/replies, xml ) | Need Help?? |
Sorry, wrong.It is not reasonable to attribute use of the offending idiom to "mindless imitation".I [...] have admitted to repeatedly doing so myself. [...] you will see others confessing also. tye comes to mind offhand. I've scanned all of the threads you linked to and have to assume that you have grossly misrepresented what I said in (tye)Re: You Say "Cargo Cult" like it's a BAD thing!: I've come to hate the term "cargo cult" myself. Many people copied that constructor code from standard documentation. I thought such copying was more accurately called "best practices".You'll note the conspicuous lack of "mindless" or any synonyms thereof. If I thought the copying in question was "mindless", would I have described it as "best practices"? I copied that because I understood it and liked it. There was nothing mindless about it. The most direct alternative is to have $obj->new() be interpretted as "$obj"->new() or something like "Class::Next=HASH(0xdeadbeef)"->new() which is just ridiculous! I wonder how many of your classes have this problem. A more reasonable alternative would be: but I haven't seen anyone advocating that yet. It is very Perlish to DWIM in such a case. In the face of the options available to handle this problem, I support the standard documentation presenting the simple DWIM work-around that leads to reasonable behavior in more cases. It is a very simple approach and it is more "robust" rather than "strict". IMO, it is the best choice (by far) for introductory writings on Perl OO. In a much more advanced treatment of Perl OO, I'd expect much more discussion of the problems with that and the reasonable alternatives to it. I have covered two alternatives above (though I only consider one to be reasonable). If I didn't want to allow $obj->new() then I would separate my class methods from my object methods by putting the class methods in one package and having constructors create objects blessed into a different package that contains only the object methods. But that creates quite a few other complications, especially if you want to "support" willy-nilly inheritance which the beginning Perl OO documents appear to want you to do. It is rather funny how much ire is directed at that one line. It brings out wails about 'cloning' and yet no cloning is done in that line. You should be complaining about some other line of code that actually copies data from the old object to the new. And, since I've read and scanned lots of notes on this topic and don't recall seeing an example of what to replace that line with, I assume that you want me to avoid this type of example: in favor of this: so that my users can see this: and have probably no clue what the heck went wrong. There must be some examples of what alternative I should use somewhere in one of these long threads. Someone find one so we can see it. It is certainly rare that such gets shown. But I choose to use the oft-hated idiom for more than just that reason. I find that when writing a Perl module for public consumption, there are usually options that I want to give to potential users of my module. I want to support my module being used in more than one place. I want to support each place that uses my module to select the options that make the most sense in the situation at hand. I expect the people who use my module to often want to deal with more than one object at once. I think modules should have unique names and so they tend to have rather long names. So I like to let the module user just mention the module name once (in a use statement) and get a customizable factory object put into a lexical variable with a name that suits their needs. In fact, I had to go back and make Win32::TieRegistry->new() even work because I found that people expected that to work despite it never being mentioned in the documentation for that module. So instead of having to write, over and over: I let you just do: Now, whether that is "clone" or "new" doesn't much matter to me. [ In fact, you can use $reg->open("key") to get the same thing. I prefer open() but support new() because of the expectations of Perl programmers. ] But the design of new()/open() that the key name is required so that it doesn't really make much sense as a "clone" method since it will be opening a new key. Sure, it copies the options from the object being used as a factory into the newly created object, but I would never name such an operation "clone" ("Here is my clone.", "Um, why doesn't he look just like you?"). You could call it "copy" but that isn't a great fit either. I can see where you might not like "new" because you could read it as "shiny new, having no baggage from anywhere else". Well, I say get over that interpretation if you are doing Perl OO. You see all of the grief it is causing you. In my case, use open() instead. But if you think of "new" as meaning "create an object", then you can use that. So, you see, in Perl OO, there is no distinction between class methods and object methods (they are both just subroutines in the same package) so I like to make my Perl objects have the ability to be both objects and factories. It is nice to be able to create a not-fully-initialized object for when it is convenient to set some aspect of the object before you set others. So it is only natural to be able to use those as factories as well. Sure, in some other OO language I would probably have a separate factory class and would prevent you from creating partially initialized objects so that I wouldn't have to make each method check "is this one ready yet". That is often a very good idea. It is like strict.pm, being less convenient and more strict in hopes of catching mistakes earlier. Note, there are things about the latest Win32::TieRegistry that I don't like. For example, exporting the factory object was a bad idea and I haven't quite worked around that early mistake as much as I'd like to yet. But I very much like my ref($class)||$class and I copied it from the standard documentation after reading about it, understanding it, and consciously deciding to use it. I understand it even better now and like it even more. And it is the best technique for new Perl OO programmers to use in order to prevent confusion. So I even like it when it is mindlessly copied (though I'd rather people not program mindlessly, but I don't always get to control that). Some other alternatives (which I haven't noticed the haters-of-this-idiom putting forth) are better for more long-term, big-project, careful, strict coding projects. Such projects should have careful coding standards and not be mindlessly copying stuff out of beginner manuals. If this is a problem that you run into then I suggest you get some coding standards for your project rather than trying to enforce coding standards on the rest of the Perl world (since Perl is such a DWIM/convenience language and Perl OO just doesn't do "strict" very well, IMHO). - tye
In Section
Meditations
|
|