【问题标题】:Basic OOP concept in PerlPerl 中的基本 OOP 概念
【发布时间】:2017-06-19 15:39:18
【问题描述】:

我正在学习 Perl 中的 OOP 概念,其中语法与 Java 不同,我曾经学习过 OOP 概念。

我有一个例子来声明一个类Person,但我有点困惑。

代码如下

package Person;

sub new {

    my $class = shift;

    my $self  = {
        _firstName => shift,
        _lastName  => shift,
        _ssn       => shift,
    };

    # Print all the values just for clarification.

    print "First Name is $self->{_firstName}\n";
    print "Last Name is $self->{_lastName}\n";
    print "SSN is $self->{_ssn}\n";

    bless $self, $class;

    return $self;
}

从上面的例子中,my $self 是标量变量还是散列变量?

据我所知,Perl 中的散列变量用% 声明,而$ 用于标量变量。

bless 函数有什么用?为什么返回$self

【问题讨论】:

  • 参见Moose 了解 Perl 中更现代的 OO。
  • 我建议你看这个优秀的教程:youtube.com/watch?v=LKXvG6VKew4
  • @WumpusQ.Wumbley:“你坚持“数组和散列并不特殊”是错误的” 如果你能找到一个精通 Perl 并同意的人,我会尊重你与你。而且我想你不知道教学法是什么意思。
  • 这是一个很大的话题,在perldoc perlootut 中有很好的介绍,它应该是您的 Perl 安装的一部分。您需要掌握 Perl 的基础知识,例如引用和匿名数据结构,但您需要的一切都在 perldoc 中进行了描述。我一直使用 Perl 来教授 OOP,因为它只使用基础语言提供多态、继承和封装。其他语言通过将所有内容都构建到语法中来使事情变得“更容易”,但对正在发生的事情的洞察力要少得多。
  • @simbabque:那个视频是 Moose 教程,我希望它会让 OP 更加困惑。 Perl 非常擅长指出对象只是另一个参数,而“类”只是一个名称空间。一旦您了解了这一切,很高兴让 Moose 为您创建所有基础架构,但我认为了解幕后发生的事情至关重要。

标签: perl oop


【解决方案1】:

从上面的例子来看,my $self 是标量变量还是散列变量?

$self 是一个标量变量。你可以看出来,因为它以 $ 开头。

(补充更新: 在 cmets 中,brian 指出这条规则是有缺陷的。他当然是对的 - 正如他通常所做的那样。$self 开头的 $ 显示它是一个标量 value,而不是一个标量 变量。但是如果您在开头使用 $ 以及缺少查找括号 - 例如 [...]{...} - 跟在变量名之后,那么您可以确定这是一个标量变量。)

但是你的完整代码行是这样的:

my $self  = {
    _firstName => shift,
    _lastName  => shift,
    _ssn       => shift,
};

这里,{ ... } 是一个“匿名哈希构造函数”。它创建一个散列并返回对它的引用。引用始终是标量值,因此它们可以存储在标量变量中(这是它们存在的主要原因之一)。

所以$self 仍然是一个标量变量,但它包含对哈希的引用。

那bless函数有什么用呢?

bless() 的调用有效地将类型分配给$self 变量。 Perl 需要知道对象的类型才能知道要在哪个符号表中搜索对象的方法。当我在其中运行课程时,我喜欢说bless() 就像在便利贴上写下对象的类型并将其拍在对象的额头上 - 所以,稍后,人们可以知道是什么类型是。

为什么会返回 $self?

你会这样称呼这个方法:

my $person = Person->new(...); # passing various parameters

new() 方法需要返回新创建的对象,以便您可以将其存储在变量中并在以后以某种方式对其进行操作。

但是一个 Perl 子程序返回子程序中最后一个表达式的值,而bless() 返回的是“blessed”对象,所以用上一行结束子程序就可以了:

bless $self, $class;

但是传统上更明确地返回值,所以大多数人会添加return 行。它有助于编写更好的文档代码。

【讨论】:

  • 并非所有以$ 开头的东西都是标量变量。这是错误的规则,因为人们会看到 $array[$i],应用您的规则,最终得到错误的答案。
【解决方案2】:

$self 是一个哈希引用,因此在大多数操作中它被视为一个标量。

bless 用于表示此哈希引用是给定类的对象(此处为Person,除非您有子类),因此您可以使用$object->function 调用此类的函数符号。

并且return $self 是必需的,因此您可以在调用new 时实际检索创建的对象!

【讨论】:

  • 很好,感谢您的回答,但是 $self 变量还不是很清楚,有什么文档可以参考更多解释吗?
  • @helloworld1234:我认为在开始学习面向对象编程之前,您需要更加熟悉普通的 Perl。 my $self = { _firstName => shift, _lastName => shift, _ssn => shift }是很普通的Perl,一定要先去那里。
  • "$self 是一个哈希引用,因此在大多数操作中它被认为是一个标量"什么时候不是"被认为是一个标量"?
  • “并且返回 $self 是必要的,因此您可以在调用 new 时实际检索创建的对象!” 不。new 子例程如果结束就可以正常工作在bless 行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多