perl中的UNIVERSAL 和AUTOLOAD
看到intermediate perl 14章,里面提到几个问题,在网上的一些帖子(其他书)上看到一些和书上不对应的地方,于是自己测试了一下,inter perl上写的是正确的。 梳理一下如下: Do all objects inherit from a common class?? 答:是的,perl中设定了一个类叫做 UNIVERSAL类, 在这个类中的定义的方法,被所有类继承,是最基本的类(不能乱用)。 what if a method is missing ? ?如果一个方法不存在,会怎么样: 答:这个问题从两方面说: 一方面, ? perl提供了测试的方法,即UNIVERSAL类中有三个方法isa(),can() 和VERSION(). 所有的类都能调用这三个方法(最好别重写) ? ? ? 例1 ? ? ? ? 比如有一个对象 $tv_horse 是一个Horse对象, 可以用$tv_horse->isa('Horse') 测试,返回值为true, ? ? ? ? ? ? 如果tv_horse是一个 racehorse的对象,是horse的派生类,也是正确的。 ? ? ? 例2 ? ? ? ?$tv_horse->can('swim'); ? 首先假定tv_horse是一个类对象或者类名, 这样就是判断该类中是否有swim方法。 另一方面,由于有继承存在,在测试method 是否missing的过程是一个搜索的过程, ? ? ? ? ? ? ? ? ? ? ?先寻找自己再寻找基类,一路追查下去,RACEhorse 找horse ,horse 找animal, ? ? ? ? ? ? ? ? ? ? 最后找到 UNIVERSAL类。 ? ? ? ? ? ? ? ? ? ? 如果都没有找到,can方法会返回false; ? ? ? ? ? ? ? ? ? ?但是如果不是测试,而是直接调用, 例如:$tv_horse->swim(@arg),这种 方式,除了从下到上找一遍,perl还会寻找并尝试调用 这些类中的AUTOLOAD方法, 并将参数都传给该方法的@_变量中;并且 our ?$AUTOLOAD 变量存储着 packagename::methodname ;这个例子就是 ?RACEHORSE::swim ?。 ? ? ? ? ? ? ? ? ?即直接调用,有可能搜索两遍。 可以用下面的代码修改看打印顺序。 #!/bin/perl { package Grandpa; $name = "Gramps"; sub greetme { print "greetme in grandpan"; } sub AUTOLOAD { print "autoload in grandpa package.[autoload]n"; } } { package Parent; our @ISA =qw(Grandpa); sub greetme { print "greetme in parentsn"; } sub AUTOLOAD { print "autoload in parent package.[autoload]n"; } } { package UNIVERSAL; sub greetme{ print "greeta in Universaln"; } sub AUTOLOAD { print "autoload in Universal package.[autoload]n"; } } print Parent->can('greetme') ? "cann":"cann'tn"; Parent->greetme(); 总结: 测试的时候,要确定变量是 either a blessed reference or a class name as a scalar ?,直接调用的时候也是如此;不能确定就用eval{} ? ? ? ? ? ? ? ?测试和autoload无关,调用才可能找到autoload。 ? ? ? ? ? ? ? 把基本用不到的方法放在autoload里,再用eval q{ sub swim{ ?...}}; goto &swim 配合使用,可以节约编译的时间。 ? ? ? ? ? ? ?调用方法会先找UNIVERSAL 再找AUTOLOAD,书中练习题2也印证了这一点。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |