Which alias module better to use? - perl

I want to alias values from source array to hash values
#$data{ $sth->{NAME_lc}->#* } = $self->source->#*;
What is the best way to accomplish this task?
UPD
Here I want hash value refer to array value. And if hash value is changed the corresponding value in array must be changed too

I have found this solution:
use Data::Alias;
alias #$data{ $sth->{NAME_lc}->#* } = $self->source->#*;
UPD
Thanks #amon for refaliasinglists:
\(#$data{ $sth->{NAME_lc}->#* }) = \($self->source->#*)
UPD
Seems last examples does not work. Aliases are lexically scoped. reported as RT#133538
Data::Alias still works fine
UPD
Data::Alias is most ++ aliasing module on metacpan.org so I think it is the best method as of today. Until refaliasing feature will be fixed.

Related

Type of argument to keys on reference must be unblessed hashref or arrayref

if((scalar keys ($this->{'libraries'}->{$y}->{'cellHash'})) == 0){
This is the line where I am getting the "Type of argument to keys on reference must be unblessed hashref or arrayref" error. Can you help me fix this?
I am not posting the code for obvious reasons.
The new ability of keys to take a reference is broken by design. Perl's development team couldn't figure out how it should work with some references, so it only works for some references. As such, keys's ability to accept a reference is documented to be experimental. Unable to resolve this issue, this "feature" was removed in 5.24. You shouldn't use it since your code will stop working when you upgrade your perl.
You've hit on of those case where keys doesn't work when given a reference. Provide a hash or an array instead. In this case, you probably want
keys(%{ $this->{'libraries'}->{$y}->{'cellHash'} })
The whole thing can be written as follows:
if (!keys(%{ $this->{libraries}{$y}{cellHash} })) { ... }
%{$this->{'libraries'}->{$y}->{'cellHash'}} .I missed the flower bracket and the % .

Perl alternative to hash_hmac('ripemd160', $data, $key) in PHP

I need to produce same result in Perl that hash_hmac('ripemd160', $data, $key) produces in PHP
Managed to trace it down to two perl modules, just cant get them working together...
Digest::HMAC and Crypt::RIPEMD160
use Crypt::RIPEMD160;
use Digest::HMAC;
$hmac = Digest::HMAC->new('bar', 'Crypt::RIPEMD160');
$hmac->add('foo');
$digest = $hmac->digest;
anyone got any ideas what am i doing wrong?
If i use the code above i get following error:
Can't call method "add" on an undefined value at /usr/lib64/perl5/vendor_perl/5.12.4/Digest/HMAC.pm line 28.
Since i was unable to pass the hash function reference in the code above, after looking at the HMAC module at the hmac function i thought i could write it in my code direct:
my $data = 'bar';
my $key = 'foo';
$block_size = 160;
$block_size ||= 64;
$key = Crypt::RIPEMD160->hash($key) if length($key) > $block_size;
my $k_ipad = $key ^ (chr(0x36) x $block_size);
my $k_opad = $key ^ (chr(0x5c) x $block_size);
my $digest = Crypt::RIPEMD160->hash($k_opad, Crypt::RIPEMD160->hash($k_ipad, $data));
this does produce a hash but still a wrong one
PHP generated hash: isceebbf5cd5e34c888b493cf7f7c39a7b181b65a3
The perl hash: hash21a2fa2bf39fd99d4c9cdf147added69c32d45f9e
To be honest i dont care how its done and what modules are used as long as I get same hash as the php function produces... at this point I am tempted writing a php script that i call from perl just to get that hash... :( as I am runing out of ideas...
The Digest::HMAC only includes Digest::HMAC_MD5 and Digest::HMAC_SHA1. However, I took a look at the Perl code for Digest::HMAC_MD5. The whole thing is about 20 lines of code. It basically creates two methods:
sub hmac_md5 {
hmac($_[0], $_[1], \&md5, 64);
}
and
sub hmac_md5_hex {
unpack("H*", &hmac_md5);
}
That's pretty much the entire program.
If you forget about the object oriented style of the package, and use the functional style, it looks like this might work for you:
hmac($data, $key, \&ripemd160, 160);
or maybe just:
hmac($data, $key \&ripemd160);
In fact, that's documented on the CPAN Digest::HMAC page itself.
I am perhaps a bit late in this discussion but when talking about Crypt::Digest::RIPEMD160 (I am the author of this module :) you can easily create HMAC with Crypt::Mac::HMAC from the same family of modules.
It is as simple as:
use Crypt::Mac::HMAC 'hmac';
$hmac_raw = hmac('RIPEMD160', $key, $data);
The reason your code doesn't work is that, while the interface provided by Crypt::RIPEMD160 looks similar to the standard Digest interface, it's not quite compatible: in particular, the reset() method of Crypt::RIPEMD160 apparently doesn't return a reference to the object it's called on, and the code in Digest::HMAC happens to rely on that detail.
This incompatibility would be a trivial things to fix by slightly tweaking either module, either to add the missing return value to Crypt::RIPEMD5 or to make Digest::HMAC less reliant on needless method chaining. The latter would be as easy as changing the line:
$self->{hasher}->reset->add($self->{k_opad}, $inner_digest);
in Digest::HMAC to:
$self->{hasher}->reset;
$self->{hasher}->add($self->{k_opad}, $inner_digest);
(Of course, I'm not suggesting that you do this yourself, although you could report the issue to the maintainers of those modules.)
However, with both modules as they currently are, it just won't work. The solutions I'd recommend would be to either use the non-OO interface, as David W. suggests, or try the newer Crypt::Digest::RIPEMD160 module, which properly implements the Digest interface and should play nicer with Digest::HMAC.
Edit:
Actually, David W.'s suggestion won't work as given, because Crypt::RIPEMD160 doesn't export a non-OO ripemd160() function. You could, however, easily create one:
use Crypt::RIPEMD160;
sub ripemd160 {
return Crypt::RIPEMD160->hash( join "", #_ );
}
and then use it like this:
use Digest::HMAC qw( hmac );
sub hmac_ripemd160 {
return hmac( #_[0, 1], \&ripemd160, 64 );
}
(Yes, 64 bytes is the correct block size from HMAC-RIPEMD160, since the input block length of RIPEMD160 is 16 32-bit words, which equals 512 bits or 64 bytes. In practice, using the wrong input block size is very unlikely to cause any issues, other than for interoperability of course, but the security proof of the HMAC construction assumes, for simplicity, that the key is padded to be exactly one input block long. Thus, and in order to ensure that all implementations of HMAC-RIPEMD160 produce the same output for the same key and message, it's best to stick to this rule.)
Edit 2: OK, I tried to test the code I posted above against the HMAC-RIPEMD160 test vectors from RFC 2286, and just could not get the results to match. What I finally realized was two things:
The non-OO hmac() function exported by Digest::HMAC assumes that the custom hash function passed to it will accept multiple parameters and concatenate them. My original implementation of the ripemd160() wrapper above did not (but I fixed it so that now it does). This is arguably a bug in Digest::HMAC, or at least in its documentation.
The Crypt::RIPEMD160 module comes with the submodule Crypt::RIPEMD160::MAC, which already implements HMAC-RIPEMD160, even though, for some perverse reason, the documentation doesn't actually use the name HMAC. If you look at the code, though, or just compare the output to the official test vectors, that's indeed exactly what it does.

What is the status of applying the "values" function to a hash or array reference?

Given that $struct is a data structure that can be either a hash or an array reference, I have some code that looks like this:
for (ref($struct) eq "HASH" ? values %$struct : values #$struct) {
# process $_
...
}
I would like to use the new functionality of the values function (to accept a reference to an unblessed hash or array) to write this instead, which works in my 5.14.2 release:
for (values $struct) {
# process $_
...
}
So much prettier!
But the documentation for values says that this feature is "highly experimental." It has been around for several releases now (5.12 through 5.16.0 as far as I can tell). Does anyone know what the status is? How is the experiment working out?
It's marked as experimental because it's a controversial change. It's controversial because it doesn't work on all references to hashes.* No new has been discovered since the feature was introduced, but I don't think anyone expected any new problems to be discovered.
* — values($hash) can fail where values(%$hash) would succeed. Your original code has exactly the same problem, so this "limitation" of values isn't a problem for you.

Perl dereferencing array for specific value

So, in Perl, I have an array within an object (so, a reference to an array), and I want to find the first value of that array.
I find myself using code like the following quite often:
my $server_ref = $self->{source_env}->{server};
my #servers = #$server_ref;
my $main_server = $servers[0];
That works, but I'm sure I could do this without all the intermediate lines and variables.
Can someone help me with the syntax?
Try:
my $main_server = $self->{source_env}->{server}->[0];
Try $server_ref->[0], it should work.

How can I elegantly call a Perl subroutine whose name is held in a variable?

I keep the name of the subroutine I want to call at runtime in a variable called $action. Then I use this to call that sub at the right time:
&{\&{$action}}();
Works fine. The only thing I don't like is that it's ugly and every time I do it, I feel beholden to add a comment for the next developer:
# call the sub by the name of $action
Anyone know a prettier way of doing this?
UPDATE: The idea here was to avoid having to maintain a dispatch table every time I added a new callable sub, since I am the sole developer, I'm not worried about other programmers following or not following the 'rules'. Sacrificing a bit of security for my convenience. Instead my dispatch module would check $action to make sure that 1) it is the name of a defined subroutine and not malicious code to run with eval, and 2) that it wouldn't run any sub prefaced by an underscore, which would be marked as internal-only subs by this naming convention.
Any thoughts on this approach? Whitelisting subroutines in the dispatch table is something I will forget all the time, and my clients would rather me err on the side of "it works" than "it's wicked secure". (very limited time to develop apps)
FINAL UPDATE: I think I've decided on a dispatch table after all. Although I'd be curious if anyone who reads this question has ever tried to do away with one and how they did it, I have to bow to the collective wisdom here. Thanks to all, many great responses.
Rather than storing subroutine names in a variable and calling them, a better way to do this is to use a hash of subroutine references (otherwise known as a dispatch table.)
my %actions = ( foo => \&foo,
bar => \&bar,
baz => sub { print 'baz!' }
...
);
Then you can call the right one easily:
$actions{$action}->();
You can also add some checking to make sure $action is a valid key in the hash, and so forth.
In general, you should avoid symbolic references (what you're doing now) as they cause all kinds of problems. In addition, using real subroutine references will work with strict turned on.
Just &$action(), but usually it's nicer to use coderefs from the beginning, or use a dispatcher hash. For example:
my $disp = {foo => \&some_sub, bar => \&some_other_sub };
$disp->{'foo'}->();
Huh? You can just say
$action->()
Example:
sub f { return 11 }
$action = 'f';
print $action->();
$ perl subfromscalar.pl
11
Constructions like
'f'->() # equivalent to &f()
also work.
I'm not sure I understand what you mean. (I think this is another in a recent group of "How can I use a variable as a variable name?" questions, but maybe not.)
In any case, you should be able to assign an entire subroutine to a variable (as a reference), and then call it straightforwardly:
# create the $action variable - a reference to the subroutine
my $action = \&sing_out;
# later - perhaps much later - I call it
$action->();
sub sing_out {
print "La, la, la, la, la!\n"
}
The most important thing is: why do you want to use variable as function name. What will happen if it will be 'eval'?
Is there a list of functions that can be used? Or can it be any function? If list exists - how long it is?
Generally, the best way to handle such cases is to use dispatch tables:
my %dispatch = (
'addition' => \&some_addition_function,
'multiplication' => sub { $self->call_method( #_ ) },
);
And then just:
$dispatch{ $your_variable }->( 'any', 'args' );
__PACKAGE__->can($action)->(#args);
For more info on can(): http://perldoc.perl.org/UNIVERSAL.html
I do something similar. I split it into two lines to make it slightly more identifiable, but it's not a lot prettier.
my $sub = \&{$action};
$sub->();
I do not know of a more correct or prettier way of doing it. For what it's worth, we have production code that does what you are doing, and it works without having to disable use strict.
Every package in Perl is already a hash table. You can add elements and reference them by the normal hash operations. In general it is not necessary to duplicate the functionality by an additional hash table.
#! /usr/bin/perl -T
use strict;
use warnings;
my $tag = 'HTML';
*::->{$tag} = sub { print '<html>', #_, '</html>', "\n" };
HTML("body1");
*::->{$tag}("body2");
The code prints:
<html>body1</html>
<html>body2</html>
If you need a separate name space, you can define a dedicated package.
See perlmod for further information.
Either use
&{\&{$action}}();
Or use eval to execute the function:
eval("$action()");
I did it in this way:
#func = qw(cpu mem net disk);
foreach my $item (#func){
$ret .= &$item(1);
}
If it's only in one program, write a function that calls a subroutine using a variable name, and only have to document it/apologize once?
I used this: it works for me.
(\$action)->();
Or you can use 'do', quite similar with previous posts:
$p = do { \&$conn;};
$p->();