关于同名元对象的问题

时间:2012-01-06 01:59:24

标签: perl

阅读perltooc,其中作者解释了同名的元对象。我有一些关于它的问题,我没有通过搜索找到...

1。 Hash必须被命名为对象,但如果对象的名称如My :: Good :: Class,那么同名哈希的名称是什么? 我试过了:

 package My::Good::Class
 our %Class = ( some_data => 1 );
 sub getEpoHash {
   my $class = shift;
   my $var = ref($class) || $class;
   no strict 'refs';
   return \%$var;
 }

在我写我们的%Class ...的情况下; - 它不起作用,但如果我写%My :: Good :: Class = ...; - 有用。我不明白!在这种情况下,Class是My :: Good包的哈希...或者是什么?!

2。 在文章示例中,如何使用同名元对象创建monadic类。但所有的例子都是在没有严格的情况下编写的在使用$ self之前,我是否必须在每个函数中插入没有严格的'refs',或者还有其他方法可以使用strict来重写它?

以下是示例:

package Cosmos;
%Cosmos = ();
# accessor method for "name" attribute
sub name {
    my $self = shift;
    $self->{name} = shift if @_;
    return $self->{name};
}
# read-only accessor method for "birthday" attribute
sub birthday {
    my $self = shift;
    die "can't reset birthday" if @_; # XXX: croak() is better
    return $self->{birthday};
}
# accessor method for "stars" attribute
sub stars {
    my $self = shift;
    $self->{stars} = shift if @_;
    return $self->{stars};
}
# oh my - one of our stars just went out!
sub supernova {
    my $self = shift;
    my $count = $self->stars();
    $self->stars($count - 1) if $count > 0;
}
# constructor/initializer method - fix by reboot
sub bigbang {
    my $self = shift;
    %$self = (
        name => "the world according to tchrist",
        birthday => time(),
        stars => 0,
    );
    return $self; # yes, it's probably a class. SURPRISE!
}
# After the class is compiled, but before any use or require
# returns, we start off the universe with a bang.
__PACKAGE__ -> bigbang();

2 个答案:

答案 0 :(得分:2)

perltooc的当前版本是严格兼容的,您可能正在查看旧版本。

http://perldoc.perl.org/perltooc.html#The-Eponymous-Meta-Object

最佳做法随着时间的推移而发生了变化,许多旧的代码示例都需要一些no strict 'refs',以便让他们使用限制。

关于包的同名哈希,如果你有一个名为My::Good::Class的包并且你将该字符串视为一个哈希(严格引用关闭),那么你指的是%Class哈希值。 My::Good包。

答案 1 :(得分:1)

我和彼得一样困惑所以我写了这个:

use strict;
use warnings;

sub describe
{
    my ($class) = @_;

    # Ensure class variable hash name contains "::"
    my $cv = $class . ($class !~ /::/ && "::${class}");
    # Convert symbolic ref to "hard" ref
    no strict "refs";
    $cv = \%$cv;
    use strict;
    print "$class ($cv): \"", $cv->{description}, "\"\n\n";
}

package Simple;

# "our" creates a variable in the current package
# so "our %Simple" is the same as "%Simple::Simple".

# our %Simple = (description => "Simple's package is " . __PACKAGE__);
# print "\%Simple at ", \ %Simple, "\n";

%Simple::Simple = (description => "Simple's package is " . __PACKAGE__);
print "\%Simple::Simple at ", \ %Simple::Simple, "\n";

main::describe __PACKAGE__;

package More::Complex;

%More::Complex =
    (description => "More::Complex's package is " . __PACKAGE__);

print "\%More::Complex at ", \ %More::Complex, "\n";

main::describe __PACKAGE__;

这表明,在Simple包中,our %Simple = ...实际上与%Simple::Simple = ...相同。

perltooc.html中的示例隐藏了这一点,因为它们从未尝试在其包外引用%Simple。你为什么要这样做?因为,在现实世界中,您不会在每个包中复制类变量访问代码,而是从某个超类继承它。超类代码需要知道类Simple的类变量是%Simple::Simple,就像我的describe(sort-of-)方法一样。

这个隐藏的小疣让我想知道为%Simple::class_varibles%More::Complex::class_variables等类变量设置一个固定名称是不是更简单,即使你没有通过使用这个词看起来那么聪明“同名”: - )。