我希望我知道有什么参考资料或文档告诉我这是在Perl中创建新对象的最佳方法:
sub new {
my $package = shift;
my $class = ref($package) || $package
这是我多年来创建对象的方法,但现在我想知道为什么要这么麻烦?除了一些边缘情况,为什么不简单地做以下几点:
sub new {
shift; # get rid of the object or package name
my $class = __PACKAGE__;
如果没有特殊的原因来检测调用“new”方法的命名空间,那么简单地使用__PACKAGE__会有什么问题吗?
2条答案
按热度按时间sqxo8psd1#
继承
在这个例子中,
ClassB
继承了ClassA
的方法,包括它的构造函数,但是我们仍然希望将对象标识为属于ClassB
,所以ClassA
中的构造函数必须尊重传递给它的构造函数的引用的名称。更简单、更安全
或者在
ClassB
中添加传递构造函数。fbcarpbf2#
类名已经是构造函数的第一个参数了,为什么不使用它呢?你不需要去接触任何东西,如果你认为情况比你最初想象的要复杂,你也没有人为地造成一个减速带。下面的代码可以使用继承,也可以不使用继承:
考虑一下你所编写的任何程序,如果代码情况发生变化,你需要做多少修改。也许你添加了一些你并不立即需要的额外步骤,但是当你意识到你确实需要这些情况时,这可以保持代码的灵活性。在你的例子中,您实际上必须做额外的工作来忽略Perl专门提供的invocant参数,该参数告诉您哪个类正在尝试创建新对象。
例如,你创建了你的类,它为你工作,并且很好地完成了它的工作。它工作得如此之好,以至于你可以共享它,其他人也可以使用它,他们对它很满意一段时间,直到他们需要这个小小的修改。他们应该能够子类化你的模块(因此,对它或对您来说没有任何更改)来扩展或重写方法。但是,您的代码不允许这样做,因为您使用了一种限制性更强的方式来祝福对象,而这种方式并没有带来任何好处。
你的问题中的第一段代码也使用了第一个参数,但它并不是构造函数的处方。它允许一个已经存在的对象创建一个新的对象,这是一件额外的事情。
ref
从对象中提取包名,并将其用于新对象。我不是特别喜欢这种创建新对象的方式,而且我认为它的界面可能会让人感到困惑。当你在一个已有对象上调用new时,会发生什么?你会克隆已有对象吗?如果是,还有更好的名字,比如
clone
(Ruby使用dup
)。你得到了一个完全新鲜的对象吗?如果是的话,为什么要遍历一个现有的对象来得到一个与它完全无关的对象呢?曾经有一段时间,很多OO Perl的例子都展示了同样的构造函数,它被复制并粘贴到了很多地方。但从那以后,我们学到了很多。也许你有一个很好的答案,为什么你会允许这样做,但到目前为止,我还没有听到一个令人信服的答案。