Perl:构造函数中的函数调用?

| 我想改善我的perl脚本,该脚本在cisco交换机上执行SNMP请求。但是我不是很了解构造函数,并没有给perl函数提供args。 这是我的脚本:
#!/usr/bin/perl
use strict;
use warnings;
use Net::SNMP;
package SnmpTable;

my ($session, $error);

sub new {
  my ($classe, $hostname, $oid, $community) = @_;
  my $this = {
    \"hostname\"      => $hostname,
    \"oid\"           => $oid,
    \"community\" => $community
  };
  bless($this, $classe);
  return $this;
}

sub connexion {
    my ($this) = @_;
    #print \"Connexion SNMP...\\n\";
    ($session, $error) = Net::SNMP->session(
        -hostname  => $this->{hostname},
        -community => $this->{community},
        -version   => \"1\",
        -timeout   => 3,
    );
    request_error_connexion() if (!defined($session));
    #print \"Connexion établie\\n\";
}

sub request_error_connexion {   
    my ($this) = @_;
    print \"Erreur : connexion SNMP impossible vers $this->{hostname}\\n\";
    print \"Erreur : $error\\n\";
    if ($error =~ /The argument \"-community\" is unknown/)
        {
                # protocol SNMP version 3 non pris en charge
                exit 3;  # code retour final = 3*256 = 768
        }
    else
    {
        exit 1; # code retour final = 1*256 = 256
    }
}

sub request_error {
        my ($this) = @_;
        #print \"Erreur : pas de réponse SNMP depuis l\'hôte $this->{hostname} avec l\'oid $this->{oid}\\n\";
        printf \"Erreur : %s\\n\",$session->error;
        if ($session->error =~ /No response from remote host/)
        {
                #host ok, mais community surement erronée ou host refuse le connexion
                $session->close;
                exit 2; # code retour final = 2*256 = 512
        }
        else
        {
                #table introuvable
                $session->close;
                exit 4; # code retour final = 4*256 = 1024
        }
}

sub requete {
    my ($this) = @_;
    my $result = $session->get_table( -baseoid => $this->{oid} );
    request_error() if (!defined($result));
    my %tab = ();

    foreach my $i (Net::SNMP::oid_lex_sort(keys %{$result})) {
        my $index = $i;
        $index =~ s/$this->{oid}.//;
        $tab{ $index } = $result->{$i};  
        #print $index.\"--\".$result->{$i}.\"\\n\";
    }

    $session->close();
    return %tab;
}

1;
在我的构造函数中,我想创建SNMP会话(使用Net :: SNMP),而不必在函数\'connexion()\'中进行。当我创建实例时,connexion()会自动调用。 此外,我想要带有arg(OID)的函数\'requete()\'。 因此,我只能创建一个实例,并执行所有请求。 使用该脚本,我必须创建所需的许多信息实例。 希望这是可以理解的... 谢谢。     
已邀请:
new
中,在
return
之前放置:
$this->connexion;
到OID参数部分:
sub requete {
    my ($this, $oid) = @_;

    $oid = $this->{oid}
        unless defined $oid;

    my $result = $session->get_table( -baseoid => $oid );
    request_error() if (!defined($result));
    my %tab = ();

    foreach my $i (Net::SNMP::oid_lex_sort(keys %{$result})) {
        my $index = $i;
        $index =~ s/$this->{oid}.//;
        $tab{ $index } = $result->{$i};  
        #print $index.\"--\".$result->{$i}.\"\\n\";
    }

    $session->close();
    return %tab;
}
这将接受OID作为参数,如果未提供OID作为参数,它将使用构造函数中的OID。     
我不是100%知道您的问题是什么,但是可以尝试回答以下问题: 子例程参数在Perl中如何工作? 构造函数在Perl中如何工作? 答案: 子例程参数如何工作? Perl中的子例程有点不寻常。有关所有详细信息,请参见perldoc perlsub。 简短的版本是对子例程的任何调用都会传递一个参数列表。由列表中的代码来处理所需的代码。 参数列表存储在特殊的“ 5”数组中。
@_
的成员实际上是传入的值的别名(请考虑按引用传递),因此可以修改调用参数。为避免发生意外,大多数子例程将
@_
的元素复制到局部变量中。当您看到
my ($foo, $bar) = @_;
时,它将
@_
的前两个成员复制到
$foo
$bar
中。另一个常见的成语是
my $foo = shift;
。这将从
@_
中删除第一项并将其复制到
$foo
中。 构造函数如何工作? 在Perl OO中,方法只是子例程,构造函数没有什么不同。 当您调用方法
$foo->do_this()
或ѭ16the时,
->
运算符左侧的项目称为倡导者。发起人确定将在哪种名称空间(perl术语中的包)中进行搜索。当调用者是字符串文字时,它被视为要开始搜索的包或类的名称。当调用者是标量时,它必须是一个对象。在任何一种情况下,当找到并调用该方法时,该倡导者也将作为该方法的第一个参数传递。因此,一个类方法(例如
new()
)将为其第一个参数期望一个字符串,而一个实例方法将期望一个对象。 构造函数(通常为18)通常是一个类方法,该方法创建它所属的类的实例。因此,ѭ20将创建一个新的
Foo
对象。 perl对象是通过使用bless函数与包相关联的任何引用。 让我们看一下您的构造函数,看看它是如何工作的:
sub new {

  # Unpack @_ into local variables
  # Notice that the class name is the first argument.
  my ($classe, $hostname, $oid, $community) = @_;


  # Create a reference to a hash with the arguments associated 
  # to particular keys in the hash.
  my $this = {
    \"hostname\"      => $hostname,
    \"oid\"           => $oid,
    \"community\" => $community
  };

  # Associate the hash ref with the class
  bless($this, $classe);

  # $this is now an object.  You can make method calls on it here.


  return $this;
}
由于构造函数与Perl中的任何其他方法或子例程一样,因此您可以在其中执行任何操作。一般认为,使子例程尽可能简单是一个好主意,但是没有理由不能在构造函数中创建Net :: SNMP对象。如果您制作了一个,则可能应该将其存储以备后用。
sub new {
  my ($classe, $hostname, $oid, $community) = @_;

  my $this = {
    \"hostname\"      => $hostname,
    \"oid\"           => $oid,
    \"community\"     => $community,
    \"connexion\"     => undef,
  };

  bless($this, $classe);

  # Store the connection for later.
  # You could also modify connexion so that it stores the connection for you.
  $this->{connexion} = $this->connexion;

  return $this;
}
所有这些代码都以我们要使用经典的Perl OOP方法为前提。虽然这些技术很好用,但是Moose Perl OO框架周围有大量活动。 Moose简化了在Perl中编写可靠且封装良好的OO代码的过程。 我强烈建议您拿起一本书的副本,例如Modern Perl。它将使您对Perl的OO工具有一个更新的了解,对Moose进行了介绍,并演示了许多简单的技术,这些技术将使您的代码更易于维护。 我希望这是有用的。     

要回复问题请先登录注册