# A question involving variable evaluation

**URL:** <https://www.ruby-forum.com/t/a-question-involving-variable-evaluation/132561>\
**Category:** Ruby\
**Created:** [March 21, 2008, 2:00pm UTC](https://www.ruby-forum.com/t/a-question-involving-variable-evaluation/132561 "2008-03-21T14:00:37Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![mike\_leonard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e56c9b/32.png) [@mike\_leonard](https://www.ruby-forum.com/u/mike_leonard)\
**Post date:** [March 21, 2008, 2:00pm UTC](https://www.ruby-forum.com/t/a-question-involving-variable-evaluation/132561/1 "2008-03-21T14:00:37Z")

</div>

Hello friends,

I’m working on some code that will iterate through an array of regex  
patterns and values, returning a value when the corresponding regex is  
matched:

the\_string = “foobar”  
patterns\_and\_values = [[/(foo)(.\*)/, “bar”], [/(bar)/, “foo”]]  
patterns\_and\_values.each do |p|  
the\_match = the\_string.match(p[0])  
if the\_match then  
return p[1]  
end  
end

To make this more useful, I’d like to be able to use the subexpression  
globals in the value that is returned, like so:

patterns = [[/(foo)(.\*)/, $~[0]], [/(bar)/, $~[1]]

However, what is actually returned is the value of $~[0] at the time  
that the patterns array was created, which is nil. Is there a good way  
to achieve this without resorting to eval? I’d like to keep the syntax  
of the patterns\_and\_values array as simple as possible, since this  
will be exposed to users so that they can add to it as necessary.

Thank you kindly in advance (and apologies if the above syntax isn’t  
quite right - I don’t have Ruby installed on this machine).

–Mike Leonard

---

<div class="post-metadata">

**Author:** ![mike\_leonard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e56c9b/32.png) [@mike\_leonard](https://www.ruby-forum.com/u/mike_leonard)\
**Post date:** [March 21, 2008, 4:21pm UTC](https://www.ruby-forum.com/t/a-question-involving-variable-evaluation/132561/2 "2008-03-21T16:21:42Z")

</div>

On Mar 21, 7:57 am, mike leonard [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> if the_match then
> 
> ```
> 
> that the patterns array was created, which is nil. Is there a good way  
> to achieve this without resorting to eval? I’d like to keep the syntax  
> of the patterns\_and\_values array as simple as possible, since this  
> will be exposed to users so that they can add to it as necessary.
> 
> Thank you kindly in advance (and apologies if the above syntax isn’t  
> quite right - I don’t have Ruby installed on this machine).
> 
> –Mike Leonard

To simplify this somewhat convoluted question:

After I assign the pattern matching globals ($~[0] et al) to a  
variable, is there a way to re-evaluate this variable after a match  
has occurred, so as to keep it consistent with the actual current  
value of $~[0], as opposed to what the value was when the variable was  
created?

Many thanks,

Mike Leonard

---

<div class="post-metadata">

**Author:** ![mike\_leonard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e56c9b/32.png) [@mike\_leonard](https://www.ruby-forum.com/u/mike_leonard)\
**Post date:** [March 21, 2008, 6:42pm UTC](https://www.ruby-forum.com/t/a-question-involving-variable-evaluation/132561/3 "2008-03-21T18:42:25Z")

</div>

just store a needed match position for every pattern and then use it  
like that:

string = ‘foobar’  
patterns = [[/(oo)+(._)/, 2], [/(._)bar/, 1]]  
p patterns.map {|regexp, position| string[regexp, position] }

2008/3/21, mike leonard [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

---

<div class="post-metadata">

**Author:** ![mike\_leonard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e56c9b/32.png) [@mike\_leonard](https://www.ruby-forum.com/u/mike_leonard)\
**Post date:** [March 21, 2008, 7:06pm UTC](https://www.ruby-forum.com/t/a-question-involving-variable-evaluation/132561/4 "2008-03-21T19:06:13Z")

</div>

On Mar 21, 12:41 pm, Ravil B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> just store a needed match position for every pattern and then use it like that:
> 
> string = ‘foobar’  
> patterns = [[/(oo)+(._)/, 2], [/(._)bar/, 1]]  
> p patterns.map {|regexp, position| string[regexp, position] }

Well the idea is that users will be able to create new filters just by  
appending items to the array. For example, if you wanted to convert  
FOObar to fooBAR, you could do:

```
patterns << [/(FOO)(bar)/, $~[0].downcase + $~[1].upcase]

```

How would this work with your suggestion?

---

<div class="post-metadata">

**Author:** ![mike\_leonard](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e56c9b/32.png) [@mike\_leonard](https://www.ruby-forum.com/u/mike_leonard)\
**Post date:** [March 21, 2008, 7:29pm UTC](https://www.ruby-forum.com/t/a-question-involving-variable-evaluation/132561/5 "2008-03-21T19:29:49Z")

</div>

Oh, i see. Then you can use Proc:

string = ‘foobar’  
patterns = [[/f(.\*)(b.r)/, proc {|match| match[2] + match[1].upcase }]]  
p patterns.map {|regexp, block| block.call string.match(regexp) }

2008/3/21, mike leonard [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
