【问题标题】:I can't get a class to work我无法上课
【发布时间】:2018-11-17 13:18:42
【问题描述】:

我想创建一个 Perl 类。

这是我的代码:

#!/usr/ bin/perl

package Data;

sub new
{ my ($class, $student) = @_;
$class = shift;
$student = shift;
$student = {_firstName => <>,
            _lastName => <>,
             _matric => <>,
            };
bless $student,$class;
print $student;
}
&new;    

我得到了这个错误:

main=HASH(0x215fc40) 在 source_file.pl 第 12 行 bless 中使用未初始化的值 $class。 在 source_file.pl 第 12 行明确祝福 ''(假设 package main)。


我使用 dcoder,我认为它不支持分离程序。但是尽管我纠正了它,但它仍然没有输出。我试图打印$self,但它留下了一个错误。完整代码如下:

#!/usr/ bin/perl
use strict;
use warnings 'all';

package student;

sub new {
 my $class = shift;
    my ($first, $last, $matric) = @_;
    my $self = {
        _firstName => $first,
        _lastName => $last,
        _matric => $matric,
        };
    bless $self, $class;
    }

my $self = student->new('victor','valdes','csc');
print $self;

这是错误:

学生=HASH(0x238ae98)

很抱歉,我对此很陌生,仍然不明白。

【问题讨论】:

  • 一切正常。 student=HASH(0x238ae98) 表示您有一个 student 对象,该对象由地址 0x238ae98 处的哈希形成。你需要做更多的阅读

标签: perl class


【解决方案1】:

这看起来很像一个家庭作业问题,所以我在犹豫是否给你一个完整的答案。您似乎对 Perl 知之甚少,并且几乎没有努力阅读有关 Perl 的面向对象的思想,而是使用疯狂的猜测来填补空白。你不会那样学语言的

您应该永远使用 & 号调用 Perl 子例程,并且方法需要在类或对象上调用,因此 &amp;new 应该是 Data-&gt;new(...)。此外,您编写的每个 Perl 源文件都应该以 use strictuse warnings 'all' 开头

这是一种非常奇怪的创建对象的方式。您通常会创建一个单独的 Perl 程序来执行 use Datamy $object = Data-&gt;new($student)。相反,您正在调用 &amp;new,它不传递任何参数,并且是您的未初始化值错误

的原因

你的$student 值应该是什么并不明显,但是在使用shift@_ 获取它的值之后,你然后用哈希引用覆盖它

您还应该通过new 构造函数调用传递散列内容的值,而不是让模块本身从STDIN 中读取。您也无法chomp 这些值,以便它们保留终止换行符,这是您不太可能想要的

我建议您将代码分成Data.pm(可能是Student.pm?)和main.pl,并从使用常量值而不是从键盘读取代码开始

类似的东西

学生.pm

package Student;

use strict;
use warnings 'all';

sub new {
    my $class = shift;
    my ($first, $last, $matric) = @_;

    my $self = {
        _firstName => $first,
        _lastName  => $last,
        _matric    => $matric,
    };

    bless $self, $class;
}

1;

main.pl

#!/usr/bin/perl

use strict;
use warnings 'all';

use Student;

my $student =  Student->new('John', 'Smith', 1987);

【讨论】:

  • 请不要以下划线开头。约定是:数据元素没有前缀;选项的减号(如果有);以及只有勇敢或愚蠢才能修改的那些东西的空间。 ?
  • 我从第 4 版开始就一直在使用 POerl。这是我看到的奇怪代码(不是书本)。
【解决方案2】:

如果您坚持将所有代码保存在一个文件中,那么您至少应该将“非类”代码移动到单独的包中。

#!/usr/ bin/perl

use strict;
use warnings 'all';

# Capital letters for user-defined packages, please
package Student;

sub new {
    my $class = shift;
    my ($first, $last, $matric) = @_;
    my $self = {
        _firstName => $first,
        _lastName => $last,
        _matric => $matric,
    };
    bless $self, $class;
}

package main;

# $self is only used as a variable name within methods.
my $student = Student->new('victor','valdes','csc');
print $student;

但这只是一种很好的做法,它不会真正影响代码中的任何内容。你说你得到这个输出:

学生=HASH(0x238ae98)

您将其描述为错误,但它根本不是错误这正是我对您的代码的期望。您的$self 变量(我已将其重命名为$student)是一个有福的哈希引用。如果你打印一个祝福的哈希引用,这就是你得到的。

但如果您想查看对象的更多结构,可以使用 Data::Dumper(标准 Perl 库)。

package main;

use Data::Dumper;

# $self is only used as a variable name within methods.
my $student = Student->new('victor','valdes','csc');
print Dumper $student;

这给了我:

$VAR1 = bless( {
                 '_lastName' => 'valdes',
                 '_firstName' => 'victor',
                 '_matric' => 'csc'
               }, 'Student' );

我不清楚你期望你的print() 声明会产生什么。但是,如果您想显示对象的属性,则需要在类中编写访问器方法。例如,返回矩阵值的方法如下所示:

sub matric {
    my $self = shift;
    return $self->{_matric};
}

在主包中你可以这样称呼它:

print $student->matric;

但我必须同意鲍罗丁的观点。看起来您正在尝试在 Perl 中自学面向对象编程,但对面向对象编程或 Perl 了解不多。猜测概念和语法很少是成功的方法。

我还要补充一点,您正在使用的 Perl OO 的“经典”风格在很大程度上已被现代 OO 框架(如 Moo)所取代。使用它可能会取得更大的成功。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多