1

I was looking for some sort of solution if the following setup can be interpreted as formal declaration of the variables , if possible. What i have is :

my $str_1 = "{cow}" ;

my $str_2 = "{cow}{black}{tasty_milk}";

what i want is :

(Based on above variable string is it possible to initialize a hash directly, something like :)

my %hash=();

$hash."*some operator* on $str_i"  = 'Initialized' ;

This "some operator" should make $hash to recognize as hash as it was declared earlier. i.e Input specific hash initialization.

PS: I don't want to write a function that will work on the string and get all information to initialize the hash.

11
  • 1
    You might try JSON instead, it is easy to parse into a hash Commented Mar 28, 2017 at 11:06
  • 6
    I don't understand what you're trying to say. Commented Mar 28, 2017 at 11:08
  • I suppose JSON may help. Let me see. Thanks Hakon. Commented Mar 28, 2017 at 11:12
  • See also Creating hash of hash dynamically in perl and Read config hash-like data into perl hash Commented Mar 28, 2017 at 11:28
  • I'm afraid your question is clear as mud. What is the expected output? Commented Mar 28, 2017 at 11:30

2 Answers 2

4

Say you had the following input instead:

my @path = qw( cow black tasty_milk );

Then you can use the following:

use Data::Diver qw( DiveVal );

DiveVal(\%hash, map \$_, @path) = 'value';

So, with Data::Diver, we get:

use Data::Diver qw( DiveVal );

$str =~ /^(?:\{\w+\})+\z/
   or die("Unrecognized format");

my @path = $str =~ /(\w+)/g;
DiveVal(\%hash, map \$_, @path) = 'value';

Without a module:

sub dive_val :lvalue { my $p = \shift;  $p = \( $$p->{$_} ) for @_;  $$p }

$str =~ /^(?:\{\w+\})+\z/
   or die("Unrecognized format");

my @path = $str =~ /(\w+)/g;
dive_val(\%hash, @path) = 'value';
Sign up to request clarification or add additional context in comments.

8 Comments

@reinierpost, It validates the input, parses the input, then sets the hash element. How is that not obvious?
It is obvious that it tries to do something like that, but with the question not being stated clearly and your code being extremely terse without any comments, I have trouble understanding what is going on and above all why, and I'm someone who has been working with Perl code for 20 years.
Which one is it? Is what it does obvious, or do you have a hard time understanding what it does?
It isn't obvious what it does, and it isn't obvious that it is what jordan vj wants.
@reinierpost, You are gravely mistaken. It's very obvious that a check that results in die("Unrecognized format") checks if the input is in a recognized format. I can't believe I have to tell you that if you've ever programmed before (in any language).
|
0

Try the following with anonymous hash

use Data::Dumper;
use warnings; 
use strict;

my $str_2 = "{cow}{black}{tasty_milk}";
my %hash;
my $ref =\%hash;
my $val;
my $lp = () = $str_2=~m/\}/g; #count the number of }
my $i = 1;
while($str_2=~m/\{(\w+)\}/g)
{
    $val = $1;

    last if ($lp == $i); 

    $ref->{$val} = {}; #make the anonymous hash        

    $ref = $ref->{$val};   #add the data into anonymous hash

    $i++;

}
$ref->{$val} = "value"; #add the last value

print Dumper \%hash;

3 Comments

By the way, my $ref =\%hash; my $val; my $lp = () = $str_2=~m/\}/g; my $i = 1; while($str_2=~m/\{(\w+)\}/g) { $val = $1; last if ($lp == $i); $ref->{$val} = {}; $ref = $ref->{$val}; $i++; } $ref->{$val} = "value"; simplifies to my $p = \\%hash; $p = \( $$p->{$1} ) while $str_2 =~ /\{(\w+)\}/g; $$p = "value";
@ikegami It is very amazing. I have tried to know your trick but I can't please shall you explain this.? :)
The trick is to add a layer of indirection. More about this here and here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.