美文网首页Perl小推车
第九章 管理真实的程序(八) -重载

第九章 管理真实的程序(八) -重载

作者: 可以没名字吗 | 来源:发表于2016-04-05 21:56 被阅读66次

    重载

    Perl不是一切皆对象的语言。它的核心数据类型(标量、数字、哈希)都不是对象(当然也没有方法),但是你可以控制自己的类和对象在特定情形下(特定语境或特别的强制转换)行为,而这就是重载。

    重载机制微妙而强大。一个有趣的例子就是重载后一个对象在布尔语境下的行为,通常在布尔语境中对象会评估为真值,但是你可以通过重载来改变这种行为。为什么想要改变这种行为呢?因为你可能期望达到这样一个效果:一个空的对象在布尔语境中被评估成假值。

    你可以重载对象在这些情形(语境或操作符)下的行为:字符串化、数字化、布尔化、迭代、调用、数字访问、哈希访问、数字操作符、比较操作符、智能匹配、位操作符甚至是赋值。字符串化,数字化和布尔化是最重要、最常见的重载情形。(实际就是字符串语境、数字语境、布尔语境)

    重载常见的操作符

    编译指示overload用来连接要重载的符号和期望的行为。使用时参数时成对传递:要重载的符号为键,函数引用为值。一个名叫Null的类将重载在布尔语境下的行为,让它在布尔语境中总是返回假值:

    package Null
    {
    use overload 'bool' => sub { 0 };
    ...
    }
    

    也很容易增加在字符串语境下的行为:

    package Null
    {
    use overload
    'bool' => sub { 0 },
    '""' => sub { '(null)' };
    }
    

    重载数字化行为很复杂,因为算术操作符往往是2元的。若2个重载过的操作数相加,那么哪一个重载行为会先发生呢?这个答案必须要是一致且容易理解的,即使是没有读过源代码的人也要能理解。

    在perldoc overload中使用2元操作符的调用约定和自动生成机制来解释。但是最简单的解决方案就是重载数字化行为('0+')并且提供一个回退方案:

    package Null
    {
    use overload
    'bool' => sub { 0 },
    '""' => sub { '(null)' },
    '0+' => sub { 0 },
    fallback => 1;
    }
    

    设置fallback为真值就是让Perl可以使用任何其他定义过的重载行为来匹配请求的操作;如果仍然不行的话,Perl就当作没有重载过,这通常是你想要的行为。

    如果没有fallback,Perl将只能使用你提供的重载行为。如果有人尝试执行额外的操作,Perl将抛出异常。

    重载和继承

    子类将会从父级(祖先)那继承重载行为。重写重载行为有2种方式。如果父类中的重载行为使用的是函数引用,那么子类也必须使用相同的形式来重写重载行为。

    如果重载行为使用的是名字而不是函数引用,这样子类可以通过重写该方法来重写重载行为:

    package Null {
    use overload
    'bool' => 'get_bool',
    '""' => 'get_string',
    '0+' => 'get_num',
    fallback => 1;
    
    sub get_bool { 0 }
    }
    

    这样任何子类都能通过重写get_bool()来改变布尔化情形下的行为:

    package Null::ButTrue {
    use parent 'Null';
    
    sub get_bool { 1 }
    }
    

    使用重载

    重载是一个用来产生新行为的捷径。CPAN上的IO::All分发包将这个想法发挥到了极限,实现了简单而优雅的API。很多的API都可以通过使用重载来变得焕然一新。

    在矩阵类上重载加、乘、甚至连接操作后用起来就会更加顺手。当然这是因为本来矩阵里面就有这些操作符号,如果一个新的问题领域里并不存在这些符号,那么你就不得不自己想办法如何让Perl中的操作符来与之匹配。

    《Perl最佳实践》对重载有着另外的建议:不要滥用。例如,对于不应该数字化表示的对象,将数字化重载为croak()函数,这样能帮助你发现和修复程序BUG。

    相关文章

      网友评论

        本文标题:第九章 管理真实的程序(八) -重载

        本文链接:https://www.haomeiwen.com/subject/qgrslttx.html