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

在perl类的构造函数中定义方法,perl,perl-module,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 $

我正在阅读如下代码片段:

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 }

致以最诚挚的问候,

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


请参见perlmod中的。

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


参见perlmod.

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

#!/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实践(一个类通常应该有一组已知的属性,而不是每次构造实例时都可能添加新的属性),但这就是它所做的…

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

#!/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实践(一个类通常应该有一组已知的属性,而不是每次构造实例时都可能添加新的属性),但这就是它所做的