Beefy Boxes and Bandwidth Generously Provided by pair Networks DiBona
"be consistent"
 
PerlMonks  

Re: sending a scalar to the interpreter as a command

by davido (Archbishop)
on Oct 08, 2012 at 21:08 UTC ( #997877=note: print w/ replies, xml ) Need Help??


in reply to sending a scalar to the interpreter as a command

there are ways to send variables to the interpreter as commands

Yes. eval (the quotish version).

my $code = 'print qq{Hello world!\n};'; eval $code;

Or, since the value returned is the value of the last expression evaluated:

my $code = '1+1'; my $result = eval $code; print $result, "\n";

I feel this answer, while probably accurate, could be a sub-optimal solution to your real problem. Many languages that are considered quite powerful provide no equivalent to eval, and the odds are good that most of those languages could solve the problem you're working on without eval. It might be the case that if you back up a step or two, and present the actual problem you're solving, rather than how you think you would like to solve it, you might get a better answer. eval is useful, but it's one of those things that usually can be avoided for the better.


Dave


Comment on Re: sending a scalar to the interpreter as a command
Select or Download Code
Re^2: sending a scalar to the interpreter as a command
by silentq (Novice) on Oct 08, 2012 at 22:39 UTC

    Thanks for your quick response, David. I really appreciate it.

    I would actually prefer to solve the problem without resorting to eval just as you have recommended. But, for some reason, I just can't quite wrap my head around how to do it. Maybe you or someone else can help.

    What I have is a two-dimensional array filled with scores. That looks something like this:

    67 42 99 28 15 14 92 12 45 57 16 41 99 67 28 15 57 12 45 14 92 12 92 42 67 28 15 45 57 16 12 99 14

    The array can be varying widths and heights. In other words, there are variable numbers of rows and columns.

    What I want to do is find all the possible combinations when taking one item from each row. I believe there are x^y possible combinations where x represents the number of rows and y represents the number of columns. What I want is this: 67-41-92, 67-41-42, 67-41-67, 67-41-28 ...

    I believe it's just a matter of nesting arrays. The trick is setting up a dynamic number of these. I played around with the idea of using a while loop, but the problem is that this resulted in consecutive iterations through the arrays, not nested iterations.

    So I'm really at a loss at this point. If anyone can help, I'd be very grateful.

    Thanks,

      #! perl -slw use strict; sub loops { map { my $n = $_; @_ ? map{ $n . '-' . $_ } loops( @_ ) : $n; } @{ shift() }; } my @arrays = map [ split ], <DATA>; print for loops( @arrays ); __DATA__ 67 42 99 28 15 14 92 12 45 57 16 41 99 67 28 15 57 12 45 14 92 12 92 42 67 28 15 45 57 16 12 99 14

      Produces:

      67-41-92 67-41-42 67-41-67 67-41-28 67-41-15 67-41-45 67-41-57 67-41-16 67-41-12 67-41-99 67-41-14 67-99-92 67-99-42 67-99-67 ... 16-92-12 16-92-99 16-92-14 16-12-92 16-12-42 16-12-67 16-12-28 16-12-15 16-12-45 16-12-57 16-12-16 16-12-12 16-12-99 16-12-14

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      RIP Neil Armstrong

        My apologies to BrowserUK whose earlier post I missed somehow.

        Your solution seems to do everything I needed to do. I'll play around with it and let you know if I have any additional questions, but that seems to work for now. Thanks so much!

        Thanks to everyone else, too, for your excellent suggestions. Clearly, I need to pay more attention to glob and look for more opportunities to take advantage of its functionality.

      What I want is this: 67-41-92, 67-41-42, 67-41-67, 67-41-28 ...

      glob can help with this:

      use strict; use warnings; my $a = join ',', qw/67 42 99 28 15 14 92 12 45 57 16/; my $b = join ',', qw/41 99 67 28 15 57 12 45 14 92 12/; my $c = join ',', qw/92 42 67 28 15 45 57 16 12 99 14/; print "$_\n" for glob "{$a}-{$b}-{$c}";

      Output:

      67-41-92 67-41-42 67-41-67 67-41-28 ... 16-12-16 16-12-12 16-12-99 16-12-14
        Beautiful use of glob, I love it, thank you Kenosis!

      G'day silentq,

      Welcome to the monastery.

      Extending ++Kenosis' excellent idea of using glob, here's a solution for variable rows and columns.

      #!/usr/bin/env perl use 5.010; use strict; use warnings; say for glob '{' . join('}-{' => map { join ',' => split } <DATA>) . ' +}'; __DATA__ 1 2 3 4 5 6 7 8 9

      Output:

      $ pm_2d_comb.pl 1-3-6-8 1-3-6-9 1-3-7-8 1-3-7-9 1-4-6-8 1-4-6-9 1-4-7-8 1-4-7-9 1-5-6-8 1-5-6-9 1-5-7-8 1-5-7-9 2-3-6-8 2-3-6-9 2-3-7-8 2-3-7-9 2-4-6-8 2-4-6-9 2-4-7-8 2-4-7-9 2-5-6-8 2-5-6-9 2-5-7-8 2-5-7-9

      -- Ken

        Thanks very much for your responses, guys. I've learned a lot, but I don't think I'm quite there yet. I took Kenosis's code and turned it into this:

        use strict; use warnings; my @array = ([0,.95,.114,0], [1,0,0,1], [1,3,5,7]); my $var; my @a; for (my $i = 0; $i <= $#array; $i++) { $a[$i] = join ',', @{$array[$i]}; $var .= "\{\$a\[$i\]\}-"; # can't use singl +e quotes here because $i won't resolve } #my $a = join ',', @{$array[0]}; #print "$_\n" for glob "{$a[0]}-{$a[1]}-{$a[2]}"; #this line works, + but it's not dynamic, ie. always prints out exactly three lines print "$_\n" for glob $var; #this line doesn' +t work; apparently you can't resolve a variable to glob (?) print "$var\n\n"; #this line shows +what the $var variable is passing to glob in line 17

        The 'for' loop works fine for the first step, but I get tripped up on the second step. I thought I might be able to push the new reference onto a variable each time through the loop and then pass that variable to glob, but I tried it with and without quotes, and it doesn't seem to work.

        As for kcott's idea, try as I might, I cannot parse the following line of code:

        say for glob '{' . join('}-{' => map { join ',' => split } <DATA>) . ' +}';

        I understand what join does, and I also understand map and split. But the way they are combined here is a little bit beyond my ability to comprehend. For example, where is the second argument for the first join?

        In any case, the problem that remains seems to be getting each row of the array together into one glob statement. If I could do that, the modified Kenosis code above would work, I think.

        Thanks again to everybody for the time you have taken to help me try to get this resolved.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://997877]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2014-04-21 02:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (489 votes), past polls