$class = ref $class || $class
by rir (Vicar) on Feb 26, 2003 at 21:58 UTC
|
I've never considered $foo->new() to indicate cloning,
but rather a better looking way to say (ref $foo)->new().
I accept the $class = ref $class || $class as
a Perl-specific idiom and so don't find it confusing.
It is a bad
idiom though. In itself it reads as nonsense: class is
the ref of class or class. Worse is the habit that you
have acquired: to think that $foo->new; is
shorthand for (ref $foo)->new;. This is bad
because they don't mean the same thing unless you know the
internals of new. Also if you don't
know the type of $foo you should explicate
this fact with ref $foo not leave the issue
in doubt.
As this use is idiomatic Perl it is not too confusing once
you realize a codebase uses the idiom.
However it is sloppy, it spreads in a codebase and is
some work to undo. I write something inside my
new (for no reason) that allows you to imply
different meanings (for no reason)
through the different usages that I allowed
(for no reason). Sloppy.
It buys nothing.
It will give pause to the better OO programmers who are
new to Perl. | [reply] [d/l] [select] |
|
|
Howdy!
I usually take 'ref $class || $class' to allow me to use
an extant object to call the constructor instead of uaing
a class name.
Of course, we always check the documentation before
assuming we know how the module works, right? And we
module authors make clear how one is expected to call
the constructor (and any other methods) in our docs,
right?
yours,
Michael
| [reply] |
|
|
I usually take 'ref $class || $class' to allow me to use an extant object to call the constructor instead of uaing a class name.
Sure. I've used and written such
myself.
I wrote such code only because I was following
the examples given me in the docs. No other reason.
The point is Why? Why do you let users of your
package use objects to call constructors?
Why do you want to be able to write $obj->new vs
Obj->new?
What is the
benefit of this more complicated and slower code?
| [reply] [d/l] [select] |
|
|
|
|
|
|
|
Re5: Constructor/Factory Orthodoxy
by dragonchild (Archbishop) on Feb 26, 2003 at 15:03 UTC
|
Cloning is a separate balliwack from from constructors. That's the crux of why I'm saying that $class = ref $class || $class; is a bad construct. It's saying that this method can be called either as Foo->new() or $foo->new(). That shouldn't be allowed. I would prefer to see die "new() is a class method!" if ref $class; instead.
And, yes, you should say (ref $foo)->new(); or, better, my $classname = ref $foo; $classname->new();. (Though, I don't know why you'd ever want to do that. Anytime I've ever seen that, I always saw a restructuring that would improve the code and remove that construct.)
------ 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. | [reply] [d/l] [select] |
|
|
I find it almost comical that this one construct gives so many people angina. I agree that cloning is separate and different. To clone means to make identical. To make a new instance of something means just that: make a new one. So in my mind you can do both. Offer a clone method if you truly are going to make an exact copy of the referent; offer a new method that allows instances as referents if you want to allow someone to make a new one like them. In other words, I don't see the dual constructor as two distinct methods (new and clone) but rather as two ways of asking for a new instance. I don't see the great value in forcing the caller to create the class name each time. In my mind new one of this class and new one like this one I already have are basically the same thing that this one simple line in one place can deal with. I believe the only reason people get so uptight about it is that traditional OO languages don't allow or offer it. If we follow that line of thinking we also should require set names for constructors, no inheritence of constructors, and (according to most) no multiple inheritence.
| [reply] |
|
|
"new" means to make a completely new one. Cloning doesn't mean to make a new one. It means copy this one. The big difference is when the object has a list of other objects contained within it. What does clone mean in this case? Does A and B both point to the same list (shallow copy)? Does B have its own list, each with clones of those contained objects (deep copy)? It's not clear, and that's because a given application might want either behavior, or something completely different. When something isn't clear, it should be made clear. Making it clear, in my mind, involves different methods. Maybe they share a bunch of stuff under the hood, but that's a good thing. There should be different presentations for different actions, though.
"That line", as you put it, removes the distinction between the two concepts. That's not so good. Also, if you asked most people who used it, they would have no idea why that line was there, what it was good for, and what behaviors it allowed/disallowed. That is what my angina is about. If you write a line, you should know what that line does.
------ 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.
| [reply] |
|
|
|
|
| [reply] |
|
|
"That shouldn't be allowed" is a personal statement. I'm not on p5p. I don't submit RFC's. I pontificate. :-)
------ 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.
| [reply] |