# $& write-protected?

**URL:** <https://rubytalk.org/t/write-protected/8914>\
**Category:** ruby-talk\
**Created:** [19 November 2003 11:17 UTC](https://rubytalk.org/t/write-protected/8914 "2003-11-19T11:17:17Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![ts1](https://avatars.discourse-cdn.com/v4/letter/t/a8b319/32.png) [@ts1](https://rubytalk.org/u/ts1)\
**Post date:** [19 November 2003 11:17 UTC](https://rubytalk.org/t/write-protected/8914/1 "2003-11-19T11:17:17Z")

</div>

> How do I assign my regexp-result to $& ?

$& is read-only

> irb(main):001:0\> $& = “test”

it depend what you want to do

/test/ =~ “test” # $& ==\> “test”

> **···**
>
> –
> 
> Guy Decoux

---

<div class="post-metadata">

**Author:** ![ts1](https://avatars.discourse-cdn.com/v4/letter/t/a8b319/32.png) [@ts1](https://rubytalk.org/u/ts1)\
**Post date:** [19 November 2003 13:02 UTC](https://rubytalk.org/t/write-protected/8914/2 "2003-11-19T13:02:16Z")

</div>

> Any ideas how to fake this?

Well, it’s easy to do for $’ and $`, no idea for the rest $1, …

> Any rationale why they are write-protected?

These variables are the result of a regexp against a string : it seems a  
non sense to change this result.

> **···**
>
> –
> 
> Guy Decoux

---

<div class="post-metadata">

**Author:** ![Sabbyxtabby](https://avatars.discourse-cdn.com/v4/letter/s/f08c70/32.png) [@Sabbyxtabby](https://rubytalk.org/u/Sabbyxtabby)\
**Post date:** [23 November 2003 14:22 UTC](https://rubytalk.org/t/write-protected/8914/3 "2003-11-23T14:22:13Z")

</div>

“Simon Strandgaard” wrote:

> That will work. But I also need to so assignment to $1 - $9, $', $`, $+

class MatchData  
def MatchData.(pre, match, post, \*captures)  
str = [pre, match, post] \* ‘’  
match = Regexp.quote(match.dup)

```
captures.collect! do |cap|
  c = Regexp.quote(cap)
  i = match.index(c) or raise ArgumentError,
    "Not a backreference: #{cap.inspect}"
  match[i + c.size, 0] = ')'
  match.slice!(0, i) + '('
end

str =~ /#{captures * '' + match}(?=.{#{post.size}}\z)/m
$~

```

end  
end

$~ = MatchData[\*%w/alpha beta charlie beta be e ta t a/]

p [$`, $&, $', \*$~.captures]

---

<div class="post-metadata">

**Author:** ![Simon\_Strandgaard4](https://avatars.discourse-cdn.com/v4/letter/s/ea666f/32.png) [@Simon\_Strandgaard4](https://rubytalk.org/u/Simon_Strandgaard4)\
**Post date:** [19 November 2003 13:52 UTC](https://rubytalk.org/t/write-protected/8914/4 "2003-11-19T13:52:16Z")

</div>

Aree, these values should only contain output from regexp.  
But as a paradox I am developing my own regexp engine!

I want my regexp engine to be compatible with Ruby’s, therefore I want to  
exercise the engine with the Rubicon testsuite. But rubicon uses $& and  
$1-$9. I can substitute all occurencies of $& and $1-$9 in rubicon.

If $& and $1-$9 assignment are impossible, then, then my regexp-engine  
never will get compatible with Ruby’s engine ☹

[RCR] remove write-protection of $&, $1-$9, $', $`, $+  
or perhaps let them stay write-protected, but let assignment via const\_set  
become possible?

> **···**
>
> On Wed, 19 Nov 2003 13:49:27 +0100, ts wrote:
> 
> > > Any ideas how to fake this?
> > 
> > Well, it’s easy to do for $’ and $`, no idea for the rest $1, …
> > 
> > > Any rationale why they are write-protected?
> > 
> > These variables are the result of a regexp against a string : it seems a  
> > non sense to change this result.
> 
> –  
> Simon Strandgaard

---

<div class="post-metadata">

**Author:** ![Simon\_Strandgaard1](https://avatars.discourse-cdn.com/v4/letter/s/e47c2d/32.png) [@Simon\_Strandgaard1](https://rubytalk.org/u/Simon_Strandgaard1)\
**Post date:** [23 November 2003 17:17 UTC](https://rubytalk.org/t/write-protected/8914/5 "2003-11-23T17:17:13Z")

</div>

> “Simon Strandgaard” wrote:
> 
> > That will work. But I also need to so assignment to $1 - $9, $', $`, $+

[snip fake MatchData class]

> $~ = MatchData[\*%w/alpha beta charlie beta be e ta t a/]
> 
> p [$`, $&, $', \*$~.captures]

Weew, nice. I were starting to believe that this were simply impossible.  
Surprise of today. I am grateful for your help. Thanks.

> **···**
>
> On Sun, 23 Nov 2003 06:20:06 -0800, Sabby and Tabby wrote:
> 
> –  
> Simon Strandgaard

---

<div class="post-metadata">

**Author:** ![ts1](https://avatars.discourse-cdn.com/v4/letter/t/a8b319/32.png) [@ts1](https://rubytalk.org/u/ts1)\
**Post date:** [19 November 2003 14:01 UTC](https://rubytalk.org/t/write-protected/8914/6 "2003-11-19T14:01:50Z")

</div>

> I want my regexp engine to be compatible with Ruby's, therefore I want to  
> exercise the engine with the Rubicon testsuite. But rubicon uses $& and  
> $1-$9. I can substitute all occurencies of $& and $1-$9 in rubicon.

Be carefull with this test : it was designed for the \*current\* regexp  
engine, this means, for example, that these tests must be modified for  
Onigurama. Because Oniguruma will give different results.

> [RCR] remove write-protection of $&, $1-$9, $', $`, $+

No need for this : just write an C extension which do this, and use this  
extension \*only\* for testing your regexp engine.

Nobody, except you, need to modify these variables.

Guy Decoux

---

<div class="post-metadata">

**Author:** ![Yukihiro\_Matsumoto2](https://avatars.discourse-cdn.com/v4/letter/y/b9e5f3/32.png) [@Yukihiro\_Matsumoto2](https://rubytalk.org/u/Yukihiro_Matsumoto2)\
**Post date:** [19 November 2003 14:18 UTC](https://rubytalk.org/t/write-protected/8914/7 "2003-11-19T14:18:12Z")

</div>

Hi,

> **···**
>
> In message “Re: $& write-protected?” on 03/11/19, Simon Strandgaard [qj5nd7l02@sneakemail.com](mailto:qj5nd7l02@sneakemail.com) writes:
> 
> > [RCR] remove write-protection of $&, $1-$9, $', $`, $+  
> > or perhaps let them stay write-protected, but let assignment via const\_set  
> > become possible?
> 
> If you update $~ (the match result), $&, $1, etc. would follow  
> accordingly. So that the better RCR should be to create MatchData  
> without built-in regular expression match, I think.
> 
> ```
> matz.
> 
> ```

---

<div class="post-metadata">

**Author:** ![Simon\_Strandgaard4](https://avatars.discourse-cdn.com/v4/letter/s/ea666f/32.png) [@Simon\_Strandgaard4](https://rubytalk.org/u/Simon_Strandgaard4)\
**Post date:** [19 November 2003 14:17 UTC](https://rubytalk.org/t/write-protected/8914/8 "2003-11-19T14:17:16Z")

</div>

> > I want my regexp engine to be compatible with Ruby’s, therefore I want to  
> > exercise the engine with the Rubicon testsuite. But rubicon uses $& and  
> > $1-$9. I can substitute all occurencies of $& and $1-$9 in rubicon.
> 
> Be carefull with this test : it was designed for the _current_ regexp  
> engine, this means, for example, that these tests must be modified for  
> Onigurama. Because Oniguruma will give different results.

I have about 150 testcases which I both test with Ruby’s current regexp  
engine and against my own engine. So far my engine is fully compatible.

Perhaps I should also run the tests agains Oniguruma.  
Do you know if Oniguruma can coexist with Ruby’s current regexp engine?

> > [RCR] remove write-protection of $&, $1-$9, $', $`, $+
> 
> No need for this : just write an C extension which do this, and use this  
> extension _only_ for testing your regexp engine.
> 
> Nobody, except you, need to modify these variables.

Great, so it _is_ possible… I will look at it tomorrow (C++SWIG).

> **···**
>
> On Wed, 19 Nov 2003 23:01:50 +0900, ts wrote:
> 
> –  
> Simon Strandgaard

---

<div class="post-metadata">

**Author:** ![Simon\_Strandgaard4](https://avatars.discourse-cdn.com/v4/letter/s/ea666f/32.png) [@Simon\_Strandgaard4](https://rubytalk.org/u/Simon_Strandgaard4)\
**Post date:** [19 November 2003 14:47 UTC](https://rubytalk.org/t/write-protected/8914/9 "2003-11-19T14:47:20Z")

</div>

Good idea for an RCR. I vote yes immediately for a pure MatchData class 😉

> **···**
>
> On Wed, 19 Nov 2003 23:18:12 +0900, Yukihiro Matsumoto wrote:
> 
> > In message “Re: $& write-protected?” \> on 03/11/19, Simon Strandgaard [qj5nd7l02@sneakemail.com](mailto:qj5nd7l02@sneakemail.com) writes:
> > 
> > > [RCR] remove write-protection of $&, $1-$9, $', $`, $+  
> > > or perhaps let them stay write-protected, but let assignment via const\_set  
> > > become possible?
> > 
> > If you update $~ (the match result), $&, $1, etc. would follow  
> > accordingly. So that the better RCR should be to create MatchData  
> > without built-in regular expression match, I think.
> 
> –  
> Simon Strandgaard

---

<div class="post-metadata">

**Author:** ![Aredridel1](https://avatars.discourse-cdn.com/v4/letter/a/d07c76/32.png) [@Aredridel1](https://rubytalk.org/u/Aredridel1)\
**Post date:** [19 November 2003 17:39 UTC](https://rubytalk.org/t/write-protected/8914/10 "2003-11-19T17:39:52Z")

</div>

> If you update $~ (the match result), $&, $1, etc. would follow  
> accordingly. So that the better RCR should be to create MatchData  
> without built-in regular expression match, I think.

Here, here!

I was trying to add some features to the regex engine and couldn’t for  
similar reasons. (I was trying to leverage the built-in syntax for  
regexes, but to match against tree-shaped structures… Don’t ask.)

I eventually gave up because I couldn’t create MatchData.

Ari

---

<div class="post-metadata">

**Author:** ![ts1](https://avatars.discourse-cdn.com/v4/letter/t/a8b319/32.png) [@ts1](https://rubytalk.org/u/ts1)\
**Post date:** [19 November 2003 14:24 UTC](https://rubytalk.org/t/write-protected/8914/11 "2003-11-19T14:24:17Z")

</div>

> Perhaps I should also run the tests agains Oniguruma.

yes, like said previously, Oniguruma will give you different results.

> Do you know if Oniguruma can coexist with Ruby's current regexp engine?

well, you can have 2 differents ruby : one with Oniguruma, the other with  
the GNU regexp

> Great, so it \*is\* possible.. I will look at it tomorrow (C++SWIG).

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^^^^

no need of SWIG in this case 🙂

Guy Decoux

---

<div class="post-metadata">

**Author:** ![Simon\_Strandgaard4](https://avatars.discourse-cdn.com/v4/letter/s/ea666f/32.png) [@Simon\_Strandgaard4](https://rubytalk.org/u/Simon_Strandgaard4)\
**Post date:** [19 November 2003 15:17 UTC](https://rubytalk.org/t/write-protected/8914/12 "2003-11-19T15:17:17Z")

</div>

> > Great, so it _is_ possible… I will look at it tomorrow (C++SWIG).  
> > ^^^^  
> > no need of SWIG in this case 🙂

Maybe overkill.

My first thought were to extern ‘last\_match\_getter’ from ‘re.c’ and  
just supply my own last\_match\_setter. But then I noticed the function are  
are ‘static’ (private).

How do you think I shall implement this ?

> gcc assign.c -I/usr/home/neoneye/install/ruby-1.8.1  
> /usr/lib/crt1.o: In function `_start': /usr/lib/crt1.o(.text+0x81): undefined reference to `main’  
> /var/tmp//ccu9UXrr.o: In function `Init_Assign': /var/tmp//ccu9UXrr.o(.text+0x17): undefined reference to `last\_match\_getter’  
> /var/tmp//ccu9UXrr.o(.text+0x21): undefined reference to `rb\_define\_virtual\_variable’  
> expand -t4 assign.c  
> #include \<ruby.h\>

extern VALUE last\_match\_getter();

static void last\_match\_setter(VALUE val) {  
/\* TODO \*/  
}

void Init\_Assign() {  
rb\_define\_virtual\_variable(“$&”, last\_match\_getter, last\_match\_setter);  
}

> **···**
>
> On Wed, 19 Nov 2003 23:24:17 +0900, ts wrote:
> 
> >

---

<div class="post-metadata">

**Author:** ![ts1](https://avatars.discourse-cdn.com/v4/letter/t/a8b319/32.png) [@ts1](https://rubytalk.org/u/ts1)\
**Post date:** [19 November 2003 15:25 UTC](https://rubytalk.org/t/write-protected/8914/13 "2003-11-19T15:25:59Z")

</div>

> My first thought were to extern 'last\_match\_getter' from 're.c' and  
> just supply my own last\_match\_setter. But then I noticed the function are  
> are 'static' (private).

see the struct RMatch in re.h. str is the string, regs are the  
registers. ruby use register to retrieve $&, $1, ...

see for example rb\_reg\_match\_pre() ($'), rb\_reg\_match\_post() ($`),  
rb\_reg\_nth\_match() ($&, $1, ...)

If you change the struct RMatch, this change will be reflected on $&,  
$1, ...

Guy Decoux

---

<div class="post-metadata">

**Author:** ![Simon\_Strandgaard4](https://avatars.discourse-cdn.com/v4/letter/s/ea666f/32.png) [@Simon\_Strandgaard4](https://rubytalk.org/u/Simon_Strandgaard4)\
**Post date:** [19 November 2003 15:52 UTC](https://rubytalk.org/t/write-protected/8914/14 "2003-11-19T15:52:16Z")

</div>

I bail out, maybe I will look at it tomorrow. I hoped it wouldn’t be this  
complicated (im tired). I will follow the other approach and substitution  
all occurencies of $& and $1-$9 instead.

Thanks for sharing you wisdom.

BTW: Is there a reason that functions not found in Ruby’s .H files, often  
has a ‘static’ tag, so thats impossible to extern them?

Would it make any sense to remove all ‘static’ tags?

> **···**
>
> On Thu, 20 Nov 2003 00:25:59 +0900, ts wrote:
> 
> > > My first thought were to extern ‘last\_match\_getter’ from ‘re.c’ and  
> > > just supply my own last\_match\_setter. But then I noticed the function are  
> > > are ‘static’ (private).
> > 
> > see the struct RMatch in re.h. str is the string, regs are the  
> > registers. ruby use register to retrieve $&, $1, …
> > 
> > see for example rb\_reg\_match\_pre() ($'), rb\_reg\_match\_post() ($`),  
> > rb\_reg\_nth\_match() ($&, $1, …)
> > 
> > If you change the struct RMatch, this change will be reflected on $&,  
> > $1, …
> 
> –  
> Simon Strandgaard
