[Israel.pm] hash

sawyer x xsawyerx at gmail.com
Sun Sep 11 06:20:48 PDT 2011


On Sun, Sep 11, 2011 at 4:00 PM, Chanan Berler <bc.other at gmail.com> wrote:

> is this better ?
>

No. Eval is bad! :)

Imagine you send improper text that could be interpreted as actual code.
Imagine someone else being able to send stuff to that service and sends
something malicious. Imagine someone not knowing what they're suppose to
send, and they just send commands.

Instead, I suggest one of two options:
1. Using some form of syntax to say "please look into this key, and then
that key, and then this index number for the value" and then using some
parser (or writing your own) that is able to understand it. This is what's
done in XPath, CSS selector paths, etc.
2. sending the data itself instead of sending a reference to where the data
may be. I suggest JSON,

I've gone ahead and written the 1st option, for fun:
#!/usr/bin/perl
use strict;
use warnings;

{
    package NewHash;
    use Tie::Hash;

    our @ISA = ('Tie::StdHash');

    sub FETCH {
        my ( $object, $path ) = @_;
        my @paths = split /\//, $path;
        return iterate( $object->{ shift @paths }, @paths );
    }

    sub iterate {
        my ( $object, @paths ) = @_;
        my $next = shift @paths if @paths;

        if ( ref $object eq 'HASH' ) {
            return defined $next ? iterate( $object->{$next}, @paths ) :
$object;
        } elsif ( ref $object eq 'ARRAY' ) {
            return defined $next ? iterate( $object->[$next], @paths ) :
$object;
        }

        if ( $next && ! ref $object ) {
            die 'Unsupported reference type: ' . ref $object;
        }

        return $object;
    }

}


my %hash;
tie %hash, 'NewHash';

%hash = (
    key1 => {
        key2 => [ 'val' ],
    },
);

my $location = 'key1/key2/0';
print $hash{$location}; # prints 'val'

print $hash{'key1'}; # prints { key2 => ['val'] }
print $hash{'key1/key2'}; # prints ['val']

-----

This recurses over the path, and goes deeper for every result until it
either finds the exact location or reaches a scalar, which should be the
last location. It doesn't support SCALAR refs or CODE refs or Regexp refs,
but it can be adapted to support them.

The problem here is what if the key name contains a forward slash? Ah, the
fallacy of simple parsing. :)

Good luck.
S.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.perl.org.il/pipermail/perl/attachments/20110911/1e4ff601/attachment.htm 


More information about the Perl mailing list