[array & regexp] Development - works, production not - why?

My development envrioment:

~% ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i686-darwin9]

My production envrioment:

x@x:~$ ruby -v
ruby 1.8.6 (2008-08-11 patchlevel 287) [i686-linux]
Ruby Enterprise Edition 20090610

My code:

Convert comma separated string to array of Regexps & compiles to one

Regexp.

From “test, /test/i, testoweX, test-, te?st, /te(.*)t/” makes

/(?-mix:test)|(?i-mx:test)|(?-mix:testoweX)|(?-mix:test-.)|(?-mix:te.st.)|(?-mix:te(.)t)/
def negative_terms_regexp
buffer = []
negative_terms.split(‘,’).each do |term|
term.strip!
if term.include_regexp?
buffer << term.to_regexp
else
if term.include?('
‘) || term.include?(’?')
buffer << term.gsub(“?”, “.”).gsub(“", ".”).to_regexp
else
buffer << Regexp.new(term)
end
end
end
Regexp.union(buffer.uniq)
end

Here is also my String class monkeypatch:

class String

Does string containg regexp?

def include_regexp?
if /\A/./[iomx]\Z/.match(self)
true
else
false
end
end

Convert any String to Regexp.

More info: [regexp] How to convert string "/regexp/i" to /regexp/i -? - Ruby - Ruby-Forum

def to_regexp
return Regexp.new(self) unless
self.strip.match(/\A/(.)/(.)\Z/mx)
regexp , flags = $1 , $2
return nil if !regexp || flags =~ /[^xim]/m

x = /x/.match(flags) && Regexp::EXTENDED
i = /i/.match(flags) && Regexp::IGNORECASE
m = /m/.match(flags) && Regexp::MULTILINE

Regexp.new regexp , [x,i,m].inject(0){|a,f| f ? a+f : a }

end
end

This code in development works properly, but in production, i get array
of pure strings instead of array of regexp. What’s wrong? Thanks!

Joao S. wrote:

This code in development works properly, but in production, i get array
of pure strings instead of array of regexp. What’s wrong? Thanks!

  1. Hey! The following code works properly in development:

def meth
puts x
end

but not in production. Can anyone tell me what’s wrong?

  1. Why oh why would you use ruby 1.8.7 in development and 1.8.6 in
    production? From the discussion here, it sounds like you might have
    better success using python 3.1 for development and ruby 1.8.6 for
    production.

What you need to do is to make a single file which is a complete
standalone testcase which demonstrates the problem - i.e. it works on
machine A but not on machine B.

That gives something for the other users on this list to run on their
own machines, and either report that it works on their platform, or
replicate the bug on their platform - in which case they can start
debugging it.

Joao S. wrote:

Ok, here is my test.rb:

$ ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-darwin8.11.1]

$ ruby r2test.rb
r2test.rb:38:in union': can't convert Array into String (TypeError) from r2test.rb:38:innegative_terms_regexp’
from r2test.rb:41

Ok, here is my test.rb:

class String
def include_regexp?
if /\A/./[iomx]\Z/.match(self)
true
else
false
end
end

def to_regexp
return Regexp.new(self) unless
self.strip.match(/\A/(.)/(.)\Z/mx)
regexp , flags = $1 , $2
return nil if !regexp || flags =~ /[^xim]/m

x = /x/.match(flags) && Regexp::EXTENDED
i = /i/.match(flags) && Regexp::IGNORECASE
m = /m/.match(flags) && Regexp::MULTILINE

Regexp.new regexp , [x,i,m].inject(0){|a,f| f ? a+f : a }

end
end

def negative_terms_regexp(negative_terms)
buffer = []
negative_terms.split(’,’).each do |term|
term.strip!
if term.include_regexp?
buffer << term.to_regexp
else
if term.include?(’’) || term.include?(’?’)
buffer << term.gsub("?", “.”).gsub("
", “.*”).to_regexp
else
buffer << Regexp.new(term)
end
end
end
Regexp.union(buffer.uniq)
end

puts negative_terms_regexp(“term, term2, termx”)

If i put :

(…)
end
puts buffer.inspect
Regexp.union(buffer.uniq)
end

puts negative_terms_regexp(“term, term2, termx”).inspect

I get locally:

ruby test.rb
[/term/, /term2/, /termx/]
/(?-mix:term)|(?-mix:term2)|(?-mix:termx)/

Production:

ruby test.rb
[/term/, /term2/, /termx/]
test.rb:38:in union': can't convert Array into String (TypeError) from test.rb:38:innegative_terms_regexp’

This may be ruby bug?

Joao S. wrote:

This may be ruby bug?

Nope.

$ ruby -v
ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-darwin8.11.1]

$ ri Regexp.union

---------------------------------------------------------- Regexp::union
Regexp.union([pattern]*) => new_str

 Return a +Regexp+ object that is the union of the given _pattern_s,
 i.e., will match any of its parts. The _pattern_s can be Regexp
 objects, in which case their options will be preserved, or Strings.
 If no arguments are given, returns +/(?!)/+.

    Regexp.union                         #=> /(?!)/
    Regexp.union("penzance")             #=> /penzance/
    Regexp.union("skiing", "sledding")   #=> /skiing|sledding/
    Regexp.union(/dogs/, /cats/i)        #=> 

/(?-mix:dogs)|(?i-mx:cats)/


arr = [/term/, /term2/, /termx/]
puts Regexp.union(*arr)

–output:–
(?-mix:(?-mix:term)|(?-mix:term2)|(?-mix:termx))

You should also be able to use that code in ruby 1.8.7 if Regexp.union
has the same definition in ruby 1.9:

$ri19 Regexp.union
---------------------------------------------------------- Regexp::union
Regexp.union(pat1, pat2, …) => new_regexp
Regexp.union(pats_ary) => new_regexp

 From Ruby 1.9.1

 Return a +Regexp+ object that is the union of the given _pattern_s,
 i.e., will match any of its parts. The _pattern_s can be Regexp
 objects, in which case their options will be preserved, or Strings.
 If no patterns are given, returns +/(?!)/+.

    Regexp.union                         #=> /(?!)/
    Regexp.union("penzance")             #=> /penzance/
    Regexp.union("a+b*c")                #=> /a+b*c/
    Regexp.union("skiing", "sledding")   #=> /skiing|sledding/
    Regexp.union(["skiing", "sledding"]) #=> /skiing|sledding/
    Regexp.union(/dogs/, /cats/i)        #=> 

/(?-mix:dogs)|(?i-mx:cats)/

Ok, last question, what makes the “*” difference?

Hi –

On Sun, 23 Aug 2009, Joao S. wrote:

Ok, here is my test.rb:

Regexp.union(buffer.uniq)

Try changing that to:

Regexp.union(*buffer.uniq)

I guess 1.8.7 changed the method so that it’s more tolerant of being
sent an actual array, as opposed to a bare list of strings.

David

Joao S. wrote:

Ok, last question, what makes the “*” difference?

Laziness is not a virtue.

Hi –

On Sun, 23 Aug 2009, Joao S. wrote:

Ok, last question, what makes the “*” difference?

The * “un-arrays” an array into a bare list. So this:

something(*[1,2,3])

is the same as

something(1,2,3)

and different from

something([1,2,3])

David