我想改进我的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) 所以我只能创建一个实例,并用它完成我的所有请求 使用该脚本,我必须创建我想要的实例。
希望,这是可以理解的...... 感谢。
答案 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)
我不是百分之百确定你的问题是什么,但这是一个尝试回答的问题:
数目:
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简介,以及演示许多简单的技术,使您的代码更易于维护。
我希望这很有用。