在perl的class的构造函数中定义方法

时间:2011-03-02 09:07:40

标签: perl perl-module

我正在阅读如下代码段:

sub new {
        my $pkg  = shift;
        my $args = shift;

        my @keys = keys %$args;

        my $self = bless \%{$args}, $pkg;
        $self->{'__properties'} = \@keys;

        my $class = ref($self);

        foreach my $meth (@keys) {

                if (! $self->can($meth)) {

                        no strict "refs";

                        *{ $class . "::" . $meth } = sub {
                                my $instance = shift;
                                return $instance->{$meth};
                        };
                }
        }

        return $self;
}

foreach 循环中,似乎根据参数创建了一些方法。有两行我不明白。有人可以帮帮我吗?什么是 * {} 用于?

no strict "refs";
*{ $class . "::" . $meth }

最诚挚的问候,

2 个答案:

答案 0 :(得分:1)

这会创建一个符号表别名 右侧包含对函数的引用,因此Perl将其别名为包$meth中的子例程$class

请参阅perlmod中的Symbol Tables

答案 1 :(得分:0)

正如eugene已经解释的那样,这些线操纵符号表。实际上,他们这样做是为了根据传递给构造函数的任意属性列表在类中创建只读访问器方法:

#!/usr/bin/env perl

use strict;
use warnings;
use 5.10.0;

package SomeClass;

sub new {
    my $pkg  = shift;
    my $args = shift;

    my @keys = keys %$args;

    my $self = bless \%{$args}, $pkg;
    $self->{'__properties'} = \@keys;

    my $class = ref($self);

    foreach my $meth (@keys) {

        if (!$self->can($meth)) {

            no strict "refs";

            *{$class . "::" . $meth} = sub {
                my $instance = shift;
                return $instance->{$meth};
            };          
        }       
    }   

    return $self;
}

package main;

my $foo = SomeClass->new({foo => 5});   # Creates SomeClass::foo

say $foo->foo;  # 5

my $bar = SomeClass->new({foo => 3, bar => 7});   # Creates SomeClass::bar

say $bar->foo;  # 3
say $bar->bar;  # 7
say $foo->bar;  # undef - ::bar was added to all instances of SomeClass

say $foo->baz;  # Boom!  No such method.

就我个人而言,我认为这是一个值得怀疑的OO实践(一个类通常应该有一组已知的属性,而不是每次构造一个实例时都可能添加新的属性),但这就是它的作用......