# How would this Perl script look in Ruby?

**URL:** <https://www.ruby-forum.com/t/how-would-this-perl-script-look-in-ruby/147109>\
**Category:** Ruby\
**Created:** [August 28, 2008, 2:28pm UTC](https://www.ruby-forum.com/t/how-would-this-perl-script-look-in-ruby/147109 "2008-08-28T14:28:12Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![avinash](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ed655f/32.png) [@avinash](https://www.ruby-forum.com/u/avinash)\
**Post date:** [August 28, 2008, 2:28pm UTC](https://www.ruby-forum.com/t/how-would-this-perl-script-look-in-ruby/147109/1 "2008-08-28T14:28:12Z")

</div>

Can somebody please me tell the way to write this script in Ruby?

;---------------------------------------  
#!/bin/env perl

use strict;  
use Data::Dumper;

#; define some message templates here  
my $message\_templates = [  
‘adm has _QTY_ _CAR_ cars’,  
‘ssn had _QTY_ _CAR_ cars’,  
];

#; value map  
my %value\_map = (  
‘_CAR_’ =\> {  
‘order’ =\> ‘rand’,  
‘vals’ =\> [qw(bentley merc bmw audi porsche ford honda lexus)]  
},  
‘_QTY_’ =\> {  
‘order’ =\> ‘rand’,  
‘vals’ =\> [1…10]  
}  
);

# using 'random\_msg\_stub and val generators from %value\_map

sub get\_next\_random\_msg {  
my ($next\_msg, $val\_map) = @\_;

```
my $m = &$next_msg();
while (my($vk, $v) = each (%value_map)) {
    my ($nval) = $v->{gen}->();
    $m =~ s/$vk/$nval/g;
}
$m;

```

}

# return $arrya[$last + 1] elem of array; $last is remembered across

invocations  
sub get\_seq\_val\_generator {  
my $a = $\_[0];  
my $last = 0;  
return sub {  
$last = 0 if ($last == scalar @$a);  
$$a[$last++];  
};  
}

# return random elem of array

sub get\_random\_val\_generator {  
my $arr = shift;  
return sub { return $arr-\>[rand @$arr] };  
}

#; let’s generate value generator foreach value in 'value\_map  
while (my($vk, $v) = each (%value\_map)) {  
if ($v-\>{order} eq ‘seq’) {  
$v-\>{gen} = get\_seq\_val\_generator($v-\>{vals});  
} elsif ($v-\>{order} eq ‘rand’) {  
$v-\>{gen} = get\_random\_val\_generator($v-\>{vals});  
} else {  
die “Invalid value order in value\_map\n”;  
}  
}

my ($get\_next\_random\_msg\_stub) =  
get\_random\_val\_generator($message\_templates);

while (1) {  
print get\_next\_random\_msg($get\_next\_random\_msg\_stub, %value\_map),  
“\n\n”;  
}

1;

;--------------------------------------------------

thanks in advance.

---

<div class="post-metadata">

**Author:** ![avinash](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ed655f/32.png) [@avinash](https://www.ruby-forum.com/u/avinash)\
**Post date:** [August 28, 2008, 2:34pm UTC](https://www.ruby-forum.com/t/how-would-this-perl-script-look-in-ruby/147109/2 "2008-08-28T14:34:28Z")

</div>

Why don’t you show us what you have, and where you are stuck, rather  
than us translating it for you in it’s entirety.

On Thu, Aug 28, 2008 at 09:23:30PM +0900, Avinash M. wrote:

> ```
> 'adm has _QTY_ _CAR_ cars',
> 'order' => 'rand',
> my ($nval) = $v->{gen}->();
> return sub {
> 
> ```
> 
> ;--------------------------------------------------
> 
> ## thanks in advance.
> 
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

–  
nathan  
nathan\_at\_nathanpowell\_dot\_org

At this point, anyone proposing to run Windows on servers should be  
prepared  
to explain what they know about servers that Google, Yahoo, and Amazon  
don’t.  
~ Paul Graham

---

<div class="post-metadata">

**Author:** ![avinash](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ed655f/32.png) [@avinash](https://www.ruby-forum.com/u/avinash)\
**Post date:** [August 28, 2008, 2:42pm UTC](https://www.ruby-forum.com/t/how-would-this-perl-script-look-in-ruby/147109/3 "2008-08-28T14:42:26Z")

</div>

Nathan Powell wrote:

> Why don’t you show us what you have, and where you are stuck, rather  
> than us translating it for you in it’s entirety.

sorry about that.  
things I would like to know are:

1. How would we write following method?  
the one which takes an array and return subref (whatever equivalent  
in Ruby)  
something like this(in perl)  
sub get\_random\_val\_generator {  
my $arr = shift;  
return sub { return $arr-\>[rand @$arr] };  
}

2. How to store these references(subrefs) in a hash or some variable?

3. How would you do(approach) this in Ruby(the script)?

Since I know very little about Ruby so I don’t the construct used for  
this purpose?

---

<div class="post-metadata">

**Author:** ![avinash](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ed655f/32.png) [@avinash](https://www.ruby-forum.com/u/avinash)\
**Post date:** [August 28, 2008, 2:58pm UTC](https://www.ruby-forum.com/t/how-would-this-perl-script-look-in-ruby/147109/4 "2008-08-28T14:58:33Z")

</div>

2008/8/28 Avinash M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> something like this(in perl)  
> sub get\_random\_val\_generator {  
> my $arr = shift;  
> return sub { return $arr-\>[rand @$arr] };  
> }

You can do

array = …  
rand\_gen = lambda { array[rand(array.size)] }  
…  
item = rand\_gen[] # or  
item = rand\_gen.call

> 1. How to store these references(subrefs) in a hash or some variable?

hash[some\_key] = some\_object # everything is an object

> 1. How would you do(approach) this in Ruby(the script)?

My Perl is a bit rusty and, frankly, I’m not inclined to spent the  
efforts to analyze it. Can you describe it?

Cheers

robert

---

<div class="post-metadata">

**Author:** ![avinash](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ed655f/32.png) [@avinash](https://www.ruby-forum.com/u/avinash)\
**Post date:** [August 28, 2008, 10:40pm UTC](https://www.ruby-forum.com/t/how-would-this-perl-script-look-in-ruby/147109/5 "2008-08-28T22:40:46Z")

</div>

Avinash M. wrote:

> Can somebody please me tell the way to write this script in Ruby?

just do this - no-one will ever know 😉

system “perl #{ARGV[0]}”

---

<div class="post-metadata">

**Author:** ![avinash](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ed655f/32.png) [@avinash](https://www.ruby-forum.com/u/avinash)\
**Post date:** [August 28, 2008, 10:20pm UTC](https://www.ruby-forum.com/t/how-would-this-perl-script-look-in-ruby/147109/6 "2008-08-28T22:20:44Z")

</div>

On Thu, Aug 28, 2008 at 2:51 PM, Robert K.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)wrote:

> > in Ruby)  
> > …  
> > efforts to analyze it. Can you describe it?  
> > Unless I’m mistaken, the gist of it is:

Take a bunch of templates:

adm has _QTY_ _CAR_ cars  
ssn has _QTY_ _CAR_ cars

In an infinite loop, pick one randomly, and replace the _QTY_ and _CAR_  
placeholders by values taken from the ‘vals’ fields in the following  
hash:

my %value\_map = (  
‘_CAR_’ =\> {  
‘order’ =\> ‘rand’,  
‘vals’ =\> [qw(bentley merc bmw audi porsche ford honda lexus)]  
},  
‘_QTY_’ =\> {  
‘order’ =\> ‘rand’,  
‘vals’ =\> [1…10]  
}  
);

The way values are chosen depends on the ‘order’ field, which can be  
either  
random (‘rand’) or sequential (‘seq’).

In ruby, you could replace the value\_map by using a more class-oriented  
approach:

RandomMessageValue.new(:qty, (1…10).to\_a)  
RandomMessageValue.new(:car, %w(bentley merc bmw audi porsche ford honda  
lexus)

And you have SeqMessageValue if you want something sequential.  
Both RandomMessageValue and SeqMessageValue inherit from MessageValue.  
A MessageValue object knows how to choose the next value in the array of  
values (with different implementations). Then you just need a Message  
class,  
which has a list of templates, and a list of MessageValue objects.  
Message  
knows how to replace the content of a MessageValue inside a template.

VoilÃ .

Cheers,

Emm

---

<div class="post-metadata">

**Author:** ![avinash](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ed655f/32.png) [@avinash](https://www.ruby-forum.com/u/avinash)\
**Post date:** [September 3, 2008, 6:25am UTC](https://www.ruby-forum.com/t/how-would-this-perl-script-look-in-ruby/147109/7 "2008-09-03T06:25:51Z")

</div>

On Aug 28, 7:23 am, Avinash M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> 'adm has _QTY_ _CAR_ cars',
> 'order' => 'rand',
> my ($nval) = $v->{gen}->();
> my $last = 0;
> return sub { return $arr->[rand @$arr] };
> die "Invalid value order in value_map\n";
> 
> ```
> 
> }
> 
> 1;
> 
> ;--------------------------------------------------

message\_templates =  
‘adm has _QTY_ _CAR_ cars’,  
‘ssn had _QTY_ _CAR_ cars’

get\_rand = proc{|a| a[rand( a.size )] }  
$last = -1  
get\_seq = proc{|a| $last = $last.next % a.size; a[$last] }

value\_map = {  
‘_CAR_’ =\> [ get\_seq,  
%w(bentley merc bmw audi porsche ford honda lexus) ],  
‘_QTY_’ =\> [get\_rand, (1…10).to\_a]  
}

while true do  
puts get\_rand[message\_templates].gsub( /_.\*?_/ ){|s|  
prc, list = value\_map[s]  
prc[list] }  
end

— output —  
ssn had 1 honda cars  
ssn had 10 lexus cars  
adm has 2 bentley cars  
adm has 6 merc cars  
adm has 4 bmw cars  
adm has 4 audi cars  
ssn had 7 porsche cars  
adm has 3 ford cars  
ssn had 5 honda cars  
adm has 10 lexus cars  
ssn had 7 bentley cars  
adm has 6 merc cars  
…

---

<div class="post-metadata">

**Author:** ![avinash](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/ed655f/32.png) [@avinash](https://www.ruby-forum.com/u/avinash)\
**Post date:** [September 4, 2008, 4:15pm UTC](https://www.ruby-forum.com/t/how-would-this-perl-script-look-in-ruby/147109/8 "2008-09-04T16:15:58Z")

</div>

On Sep 2, 11:20 pm, William J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > use Data::Dumper;  
> > ‘order’ =\> ‘rand’,  
> > my ($next\_msg, $val\_map) = @\_;
> > 
> > # return $arrya[$last + 1] elem of array; $last is remembered across
> 
> > ```
> > $v->{gen} = get_seq_val_generator($v->{vals});
> > 
> > ```
> 
> message\_templates =  
> ‘_QTY_’ =\> [get\_rand, (1…10).to\_a]  
> ssn had 1 honda cars  
> adm has 6 merc cars  
> …

message\_templates =  
‘adm has _QTY_ _CAR_ cars’,  
‘ssn had _QTY_ _CAR_ cars’

get\_rand = proc{|a| a[rand( a.size )] }  
get\_seq = proc{|a| a.last[a[0] = a[0].next % a.last.size ] }

value\_map = {  
‘_CAR_’ =\> [ get\_seq, [ -1,  
%w(bentley merc bmw audi porsche ford honda lexus) ] ],  
‘_QTY_’ =\> [get\_rand, (1…10).to\_a]  
}

while true do  
puts get\_rand[message\_templates].gsub( /_.\*?_/ ){|s|  
prc, list = value\_map[s]  
prc[list] }  
end
