Regexp: What does //o do?

Hi:

In a regex, what is the /o for (as opposed to n, i or g)?

EG
re = /\A\s+/o

Thanks

···


Jim Freeze

Hi,

···

At Fri, 15 Nov 2002 15:02:51 +0900, Jim Freeze wrote:

In a regex, what is the /o for (as opposed to n, i or g)?

EG
re = /\A\s+/o

This o has no meanings. It’s usefull with interpolation.

[‘\A\s+’, ‘\S+\z’].map {|s| /#{s}/} # => [/\A\s+/, /\S+\z/]
[‘\A\s+’, ‘\S+\z’].map {|s| /#{s}/o} # => [/\A\s+/, /\A\s+/]


Nobu Nakada

Hi,

In a regex, what is the /o for (as opposed to n, i or g)?

EG
re = /\A\s+/o

This o has no meanings. It’s usefull with interpolation.

[‘\A\s+’, ‘\S+\z’].map {|s| /#{s}/} # => [/\A\s+/, /\S+\z/]
[‘\A\s+’, ‘\S+\z’].map {|s| /#{s}/o} # => [/\A\s+/, /\A\s+/]

I’m confused. Why does it affect the map iterator?

[‘a’,‘b’].map {|s| /#{s}/o} # => [/a/,/a/]

Jim

···

On Friday, 15 November 2002 at 15:23:16 +0900, nobu.nokada@softhome.net wrote:

At Fri, 15 Nov 2002 15:02:51 +0900, > Jim Freeze wrote:


Nobu Nakada


Jim Freeze

You might have mail

Hi –

···

On Fri, 15 Nov 2002, Jim Freeze wrote:

On Friday, 15 November 2002 at 15:23:16 +0900, nobu.nokada@softhome.net wrote:

Hi,

At Fri, 15 Nov 2002 15:02:51 +0900, > > Jim Freeze wrote:

In a regex, what is the /o for (as opposed to n, i or g)?

EG
re = /\A\s+/o

This o has no meanings. It’s usefull with interpolation.

[‘\A\s+’, ‘\S+\z’].map {|s| /#{s}/} # => [/\A\s+/, /\S+\z/]
[‘\A\s+’, ‘\S+\z’].map {|s| /#{s}/o} # => [/\A\s+/, /\A\s+/]

I’m confused. Why does it affect the map iterator?

[‘a’,‘b’].map {|s| /#{s}/o} # => [/a/,/a/]

I think what’s happening is that the /o causes the regex to
be compiled only once, and in this case that sort of freezes
it with respect to the further iterations.

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Jim Freeze jim@freeze.org writes:

Hi,

In a regex, what is the /o for (as opposed to n, i or g)?

EG
re = /\A\s+/o

This o has no meanings. It’s usefull with interpolation.

[‘\A\s+’, ‘\S+\z’].map {|s| /#{s}/} # => [/\A\s+/, /\S+\z/]
[‘\A\s+’, ‘\S+\z’].map {|s| /#{s}/o} # => [/\A\s+/, /\A\s+/]

I’m confused. Why does it affect the map iterator?

[‘a’,‘b’].map {|s| /#{s}/o} # => [/a/,/a/]

Perhaps this is more clear:

irb(main):009:0> def foo(arg)
irb(main):010:1> p /#{arg}/o
irb(main):011:1> end
nil
irb(main):012:0> foo(‘a’)
/a/
nil
irb(main):013:0> foo(‘b’)
/a/
nil

In other words, /o means the regexp will be compiled the first time
the particular piece of code executes and the same regexp will be used
from then on. Use it only when you know the regexp will always be the
same anyway. These two examples show how it can actually introduce
bugs into your code.

···

On Friday, 15 November 2002 at 15:23:16 +0900, > nobu.nokada@softhome.net wrote:

At Fri, 15 Nov 2002 15:02:51 +0900, >> Jim Freeze wrote:

Yes. It’s not completely clear to me when it will be recompiled
and when it won’t be. Above it is not. Below it is.

irb(main):001:0> s=“a”
“a”
irb(main):002:0> /#{s}/o
/a/
irb(main):003:0> s=“b”
“b”
irb(main):004:0> /#{s}/o
/b/

I thought that your example above with the function would give the
same results as the irb example above because the re would get
destroyed when the function returned. Then I tried this:

irb(main):016:0> def foo(s)
irb(main):017:1> re = /#{s}/o
irb(main):018:1> p re
irb(main):019:1> re = nil
irb(main):020:1> end
nil
irb(main):021:0> foo(“a”)
/a/
nil
irb(main):022:0> foo(“b”)
/a/
nil

and I’m confused even more.

···

On Saturday, 16 November 2002 at 2:03:24 +0900, Matt Armstrong wrote:

Jim Freeze jim@freeze.org writes:

On Friday, 15 November 2002 at 15:23:16 +0900, > > nobu.nokada@softhome.net wrote:

Hi,

At Fri, 15 Nov 2002 15:02:51 +0900, > >> Jim Freeze wrote:

In a regex, what is the /o for (as opposed to n, i or g)?

EG
re = /\A\s+/o

This o has no meanings. It’s usefull with interpolation.

[‘\A\s+’, ‘\S+\z’].map {|s| /#{s}/} # => [/\A\s+/, /\S+\z/]
[‘\A\s+’, ‘\S+\z’].map {|s| /#{s}/o} # => [/\A\s+/, /\A\s+/]

I’m confused. Why does it affect the map iterator?

[‘a’,‘b’].map {|s| /#{s}/o} # => [/a/,/a/]

Perhaps this is more clear:

irb(main):009:0> def foo(arg)
irb(main):010:1> p /#{arg}/o
irb(main):011:1> end
nil
irb(main):012:0> foo(‘a’)
/a/
nil
irb(main):013:0> foo(‘b’)
/a/
nil

In other words, /o means the regexp will be compiled the first time
the particular piece of code executes and the same regexp will be used
from then on. Use it only when you know the regexp will always be the
same anyway. These two examples show how it can actually introduce
bugs into your code.


Jim Freeze

Tonight’s the night: Sleep in a eucalyptus tree.

Yes. It’s not completely clear to me when it will be recompiled
and when it won’t be. Above it is not. Below it is.

irb(main):001:0> s=“a”
“a”
irb(main):002:0> /#{s}/o
/a/
irb(main):003:0> s=“b”
“b”
irb(main):004:0> /#{s}/o
/b/

This is 2 different regex’s, even though they evaluate to the same,
so each one is compiled once. (2 different spots in the source code)

irb(main):016:0> def foo(s)
irb(main):017:1> re = /#{s}/o
irb(main):018:1> p re
irb(main):019:1> re = nil
irb(main):020:1> end
nil
irb(main):021:0> foo(“a”)
/a/
nil
irb(main):022:0> foo(“b”)
/a/
nil

and I’m confused even more.

That’s the SAME regex (same spot in the source code) used twice.
Your first example was 2 different regex’s, used once each.

···

=====

Yahoo IM: michael_s_campbell


Do you Yahoo!?
Yahoo! Web Hosting - Let the expert host your site
http://webhosting.yahoo.com

I’m not sure I can agree that this is the same regex, Jim is setting it to nil
at the end of the function so that also is 2 different regex objects. What
sort of voodoo is going on here? I too am confused. I didn’t know about the
/o modifier and I think it is pretty cool, now if it just made sense to
me… :slight_smile:


Signed,
Holden Glova

···

On Sat, 16 Nov 2002 10:19, Michael Campbell wrote:

Yes. It’s not completely clear to me when it will be recompiled
and when it won’t be. Above it is not. Below it is.

irb(main):001:0> s=“a”
“a”
irb(main):002:0> /#{s}/o
/a/
irb(main):003:0> s=“b”
“b”
irb(main):004:0> /#{s}/o
/b/

This is 2 different regex’s, even though they evaluate to the same,
so each one is compiled once. (2 different spots in the source code)

irb(main):016:0> def foo(s)
irb(main):017:1> re = /#{s}/o
irb(main):018:1> p re
irb(main):019:1> re = nil
irb(main):020:1> end
nil
irb(main):021:0> foo(“a”)
/a/
nil
irb(main):022:0> foo(“b”)
/a/
nil

and I’m confused even more.

That’s the SAME regex (same spot in the source code) used twice.
Your first example was 2 different regex’s, used once each.

The best I can figure is, as the last poster said, that it
is in a different position in the code. So, I guess, that
/blah/o is evaluated only once during the process, and
re is set to the evaluated regex when foo is called the
second time.

That is ok. Wierd, but ok. Now, what does it do if the RE
is defined in an eval?

···

On Saturday, 16 November 2002 at 7:46:48 +0900, Holden Glova wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I’m not sure I can agree that this is the same regex, Jim is setting it to nil
at the end of the function so that also is 2 different regex objects. What
sort of voodoo is going on here? I too am confused. I didn’t know about the
/o modifier and I think it is pretty cool, now if it just made sense to
me… :slight_smile:


Jim Freeze

Do what comes naturally now. Seethe and fume and throw a tantrum.

That’s the SAME regex (same spot in the source code) used twice.
Your first example was 2 different regex’s, used once each.

I’m not sure I can agree that this is the same regex, Jim is setting
it to nil
at the end of the function so that also is 2 different regex objects.

What I mean by “same” is that it’s the same piece of source code, not the same
object.

All that said, I’m guessing. It seems to fit the behavior, however, and I
THINK perl does roughly the same thing.

Hi –

irb(main):016:0> def foo(s)
irb(main):017:1> re = /#{s}/o
irb(main):018:1> p re
irb(main):019:1> re = nil
irb(main):020:1> end
nil
irb(main):021:0> foo(“a”)
/a/
nil
irb(main):022:0> foo(“b”)
/a/
nil

and I’m confused even more.

That’s the SAME regex (same spot in the source code) used twice.
Your first example was 2 different regex’s, used once each.

I’m not sure I can agree that this is the same regex, Jim is setting
it to nil at the end of the function so that also is 2 different
regex objects. What sort of voodoo is going on here? I too am
confused. I didn’t know about the /o modifier and I think it is
pretty cool, now if it just made sense to me… :slight_smile:

(Picking up on our irc discussion of this :slight_smile:

The assigning of the regex to a variable, followed by the assigning of
something else to the same variable, is sort of a no-op, since all it
does is increase the reference count by one and then reduce it by one.
The behavior of /o can be seen in this somewhat simpler example:

irb(main):017:0> def make_re(s); /#{s}/o; end
nil
irb(main):018:0> make_re(“a”)
/a/
irb(main):019:0> make_re(“b”)
/a/

In effect (though perhaps not really, internally), the /o modifier
seems to be sort of retro-creating a constant. So the effect is as if
one had typed:

REGEX = /a/
def make_re(s)
REGEX
end

This happens the first time through – in keeping with the “compile
once” principle of the /o – and thereafter the expression #{s} is not
evaluated dynamically again (even though it looks like it should/will
be).

In the other case that was being discussed:

irb(main):035:0> s = “a”
“a”
irb(main):036:0> /#{s}/o
/a/
irb(main):037:0> s = “b”
“b”
irb(main):038:0> /#{s}/o
/b/

there’s no connection or common context between the two regexes.
Here, it’s as if one had typed:

s = “a”
REG1 = /a/
REG1
s = “b”
REG2 = /b/
REG2

So (I assume) something like the same process of one-time compilation
is adhered to – but that’s one time per lexical regex, and two
lexically distinct regexes are not affected by each other.

David

···

On Sat, 16 Nov 2002, Holden Glova wrote:

On Sat, 16 Nov 2002 10:19, Michael Campbell wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav