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

时间:2011-04-14 12:48:08

标签: perl class constructor


我想改进我的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()会自动调用 此外,我希望函数'requete()'与arg(OID) 所以我只能创建一个实例,并用它完成我的所有请求 使用该脚本,我必须创建我想要的实例。

希望,这是可以理解的...... 感谢。

2 个答案:

答案 0 :(得分:2)

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。

答案 1 :(得分:2)

我不是百分之百确定你的问题是什么,但这是一个尝试回答的问题:

  1. 子程序参数如何在Perl中起作用?
  2. 构造函数如何在Perl中工作?
  3. 数目:

    子程序参数如何工作?

    Perl中的子程序有点不寻常。有关所有细节,请参阅perldoc perlsub。

    简短版本是对子程序的任何调用都会传递参数列表。由被调用的代码来处理它想要的列表。

    参数列表存储在特殊的@_数组中。 @_的成员实际上是传入的值的别名(考虑按引用传递),因此可以修改调用参数。为避免任何意外,大多数子程序将@_的元素复制到局部变量中。当您看到my ($foo, $bar) = @_;时,它会将@_的前两个成员复制到$foo$bar。另一个常见的习语是my $foo = shift;。这会从@_中删除第一项,并将其复制到$foo

    构造函数如何工作?

    在Perl中,OO方法只是子程序,构造函数也不例外。

    当您调用方法$foo->do_this()MyCoolClass->new()时,->运算符左侧的项目称为调用者。调用者确定将在哪个名称空间(perl术语中的包)中搜索该方法。当invocant是一个字符串文字时,它被认为是开始搜索的包或类的名称。当调用者是标量时,它必须是一个对象。在任何一种情况下,调用者也会在找到并调用时作为方法的第一个参数传入。因此,类方法(例如new())将期望第一个参数的字符串,而实例方法将期望一个对象。

    构造函数(通常为new())通常是一个类方法,用于创建它所属的类的实例。因此Foo->new()将创建一个新的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简介,以及演示许多简单的技术,使您的代码更易于维护。

    我希望这很有用。