我一直在尝试几个小时的例子,但我似乎无法掌握如何做我想做的事。
我想从子例程返回一个哈希,我认为引用是最好的选择。这里有点棘手。我想引用像$ hash {$ x}这样的哈希。我仍然是perl的菜鸟:/
1.第一个问题,我使用的例子似乎表明可以使用$ hashTable {$ login},我应该使用%hashTable {$ login}还是不重要?以下是代码:
sub authUser {
$LocalPath = "/root/UserData";
open(DATAFILE, "< $LocalPath");
while( $linebuf = <DATAFILE> ) {
chomp($linebuf);
my @arr = split(/:/, $linebuf);
my $login = $arr[1]; # arr[1] contains the user login names
my $hashTable{ $login } = "$arr[0]"; #$arr[0] is account number
}
close DATAFILE;
return \$hashTable{ $login };
}
然后我想测试这些数据以查看是否存在登录,这是我的测试方法
# test login Dr. Brule which is present in UserData
my $test = "Dr. Brule";
my $authHash = &authUser();
if ( $authHash{ $test } ) {
print "Match for user $test";
}
else {
print "No Match for user $test";
}
2.我的$ authHash应该是$ authHash {$ something},我对此感到困惑
编辑:经过一些阅读提示,仍然尝试但没有骰子,任何帮助将不胜感激
<小时/> 编辑2:任何人都可以修改我的代码,以便我能更好地理解答案吗?对不起,我似乎无法让这个工作,我已经尝试了几个小时,我真的想知道这样做的正确方法,我可以发布我的各种尝试,但我觉得这将是一种浪费房地产。
答案 0 :(得分:6)
首先,正如评论中提到的mpapec use strict; use warnings;
。这将抓住最常见的错误,包括标记你在这里询问的大部分问题(通常会提供关于你应该做什么的提示)。
现在回答问题1和2:
%hash
是哈希的整体。完整的数据结构。
$hash{key}
是哈希中的单个元素。
因此,\%hash
是对%hash
的引用,即整个哈希,在这种情况下,它似乎是您打算返回的内容。 \$hash{key}
是对单个元素的引用。
在第二个问题中,它变得棘手的是引用总是标量,无论它们引用什么。
$hash_ref = \%hash
要从您引用的哈希中获取元素,您需要先取消引用它。这通常由->
运算符完成,如下所示:
$hash_ref->{key}
请注意,从引用(->
)开始时使用$hash_ref->{key}
,但从实际哈希($hash{key}
)开始时则不是。
(作为问题2的附注,不要使用&
为子来电添加前缀 - 只需使用authUser()
代替&authUser()
。不再需要&
在Perl 5+中并且具有您通常不想要的副作用,因此您不应该养成在不需要的地方使用它的习惯。)
对于问题3,如果你只想检查一次,你也可以循环遍历数组并检查每个元素:
my $valid;
for my $username (@list_of_users) {
if ($login eq $username) {
$valid = 1;
last; # end the loop since we found what we're looking for
}
}
if ($valid) {
print "Found valid username $login\n";
} else {
print "Invalid user! $login does not exist!\n";
}
答案 1 :(得分:3)
要明确perl使用标量或列表
$scalar = 1;
@list = ( $scalar, $scalar, $scalar );
您可以通过索引$list[1]
访问每个列表项
您也可以按名称访问项目。这种结构称为哈希:$hash{ name1 }
%hash = ( 'name1', $scalar, 'name2', $scalar, 'name3', $scalar )
但是,正如您所看到的,这仍然是列表注意:()
围绕它
并且列表的每个项目只能是标量。
我没有在任何书中看到这一点,但是 $ sigil表示一个值,@表示值列表。
在此示例中,您获得一个值,因此您使用 $ sigil:
$scalar = $hash{ name1 };
$scalar = $list[ 1 ];
在此示例中,您获得值列表,因此您使用 @ sigil:
@list2 = @list1; # copy all items
@list2 = @list[ 1, 3..5 ]; # copy four items with index 1,3,4,5
@list2 = @hash{ 'name1', 'name3' }; #copy two items with index 'name1', 'name2'
perl有参考。这是一个强大的工具。
$ref = \$scalar;
$ref = \@list;
$ref = \%hash;
$ref
也是标量,因为它只有一个值。要访问此$ref
引用的基础数据,您应使用取消引用。
$scalar = $$ref;
@list = @$ref;
%hash = %$ref;
但实际上你不需要整个列表或哈希。你只想要一些物品。在这种情况下,您使用->
和 []
对perl说你想要访问列表元素,
和 {}
说perl你想要访问哈希元素:
$scalar = $ref->[ 1 ];
$scalar = $ref->{ name1 };
注意:您访问一个元素 - 使用$ sigil
如果您想要数组或散列中的元素列表,请使用@sigil。例如:
@list = @$ref[ 1, 3..5 ];
@list = @$ref{ 'name1', 'name2' };
1st:$ ref - 返回对结构的引用。 $ 表示您从变量&#39; ref&#39;中获得一个值
第二名:@ $ ref - 你解引用$ ref。 @ 表示您希望通过该引用访问列表项目。
3-a:你得到1,3,4,5&#39;数组中的项目(注意:[]
)
3-b:你得到名字1&#39;,&#39; name2&#39;来自哈希的项目(注意:{}
)
确定。但是当你引用hash或list并将这个引用放到其他hash或array时,我们可能会创建复杂的结构,如散列哈希值或散列数组哈希值。例子:
@list = ( 1, 2, 3, 4, 5 );
%hash = ( 'a', 1, b => 2 );
@list2 = ( \@list, \%hash, 3, 'y' );
%hash2 = ( name1 => \@list2, d => 4 );
%hash2 = ( 'name1', \@list2, 'd', 4 ); #same. no any difference.
$href = \%hash2;
=>
- 只需引用左操作数并将,
放在其后面。
如果您想访问&#39; hash2&#39;的一个项目:
$scalar = $hash2{ name1 };
$scalar = $href->{ name1 };
解除引用后的 $href->
意味着%hash2
如果您想访问两个或更多项&#39; hash2&#39;:
@list = @hash2{ 'name1', 'd' };
@list = @$href{ 'name1', 'd' };
解除引用后的 @$href
意味着%hash2
详细信息
$scalar = $hash2{ name1 }; # <--- What does this mean???
$hash2
表示我们可以访问%hash2的一个项。这是对列表的引用;
$list_ref = $hash2{ name1 };
$scalar = $list_ref->[ 1 ]; # <--- what we get here???
$list_ref
表示我们可以访问一个项。 ->[
表示我们可以访问列表。由于$list_ref
引用@list2
,我们可以访问\%hash
我们可以一步完成:
$scalar = $hash2{ name1 }->[ 1 ];
您可以在此处考虑替换文字:&#39; $ list_ref&#39;通过&#39; $ hash2 {name1}&#39;
我们说[ 1 ]
是指%hash
。因此,要访问该哈希的一个项,我们再次使用 $ sigil:
$hash_ref = $hash2{ name1 }->[ 1 ];
$scalar = $hash_ref->{ b };
$hash_ref
表示我们可以访问一个项。 ->{
表示我们访问哈希。由于$hash_ref
引用%hash
,我们可以访问2
我们可以一步完成:
$scalar = $hash2{ name1 }->[ 1 ]->{ b };
您可以在此处再次考虑替换文字:&#39; $ hash_ref&#39;通过&#39; $ hash2 {name1} - &gt; [1]&#39;
但hash2
这里是%hash2
。那么$href
呢?请记住这个例子:
$scalar = $hash2{ name1 };
$scalar = $href->{ name1 };
您可能会注意到,如果您通过引用访问项目,则只需添加->
即可。比较:
@l = ( 1, 2, 3, 4 );
$scalar = $l[ 1 ]; # to access to second item of @l list
$hr = \@l;
$scalar = $hl->[ 1 ]; # to access to second item of @l list
%h = @l;
$scalar = $h{ 1 };
$hr = \%h;
$scalar = $hr->{ 1 };
->
后面的括号表示[
数组或{
哈希项。
$href
怎么样?
$scalar = $hash2{ name1 }->[ 1 ]->{ b };
$scalar = $href->{ name1 }->[ 1 ]->{ b };
首次取消引用后,我们不需要->
$scalar = $hash2{ name1 }[ 1 ]{ b };
^-- first dereference
$scalar = $href->{ name1 }[ 1 ]{ b };
^--first dereference
回到你的问题。在perl中,您可以将 LIST 值传递给subs并返回 LIST 。
sub test {
return @_;
}
在这里,我们返回所有项目。
return \%hash; # fn()->{ name1 }; # actually all these is list of one item
return \@list; # fn()->[ 1 ]; # so we may write: (fn())[0]->[ 1 ];
return $scalar; # fn(); # here also list of one item
return ( $scalar, \%hash, \@list );
(fn())[ 0 ];
(fn())[ 1 ]->{ name1 };
(fn())[ 2 ]->[ 1 ];
可以使用$ hashTable {$ login},我应该使用%hashTable {$ login}还是不重要?
不。您应该使用 $ sigin从%hashTable
访问一个项。 $ hashTable {$ login} 是对的。
如果您要提取两个登录,则应使用 @ sigil:
@list = @hashTable{ 'login1', 'login2' };
# or
$l1 = 'login1';
$l2 = 'login2';
@list = @hashTable{ $l1, $l2 };
return \ $ hashTable {$ login};
错误。您从散列中返回一个项。所以返回$ hashTable {$ login} 是对的。
2.我的$ authHash应该是$ authHash {$ something},我对此感到困惑
我认为你%hashTable
是由$ login键入的哈希列表。像这样:
$login1 = { name => 'Vasiliy', pass => 'secret' } # ref to hash
%login2 = ( name => 'Petrovich', pass => '^&UDHJ' ); # just a hash
%hashTable = (
vasya => $login1, # items are always refs!!!
piter => \%login2, # items are always refs!!!
)
所以authUser
sub会返回对
my $authHash = authUser( 'vasya' ); # & is not required at all
由于$ authHash,如果引用哈希,则应使用->
if( $authHash->{ pass } eq $password ) {
...
}
但是,如果您的authUser
是解析配置文件并返回所有用户,则应将其重命名为loadUsers
并返回引用以进行哈希:
sub loadUsers {
....
return \%hashTable;
}
my $usersDB = loadUsers;
if( $usersDB->{ $login }->{ pass } eq $password ) {
print 'You have granged access';
}
else { ... }
编辑2:任何人都可以修改我的代码,以便我能更好地理解答案吗?
不。阅读我的教程。要了解如何编写代码,您应该自己完成。
AS ADVICE
当你新手时:
->
来访问项目。
$list = [ 1, 2, 3 ];
$hash = { a => 1, b => 2 };
$list->[ 2 ];
$hash->{ b };
例外情况是您访问整个数组或哈希:
@l = @$list;
%h = %$hash;
@l = keys %$hash;
@l = values %$hash;
答案 2 :(得分:0)
你可能不想这样做:
return \$hashTable{ $login };
您正在返回哈希的引用(指针)。 试试吧
return $hashTable{$login}
将返回帐号。
或者,如果你真的想要一群哈希,那么
return \ $ hashTable
很好(不要添加{$ login}部分),但另一方面你需要 解除引用。
例如:
my $p = authUser()
if ($p->{'Dr. Brule'})
...
注意 - &gt;在那里。它取消引用您传回的指针。