Index: src/org/jruby/RubyRegexp.java
===================================================================
RCS file: /cvsroot/jruby/jruby/src/org/jruby/RubyRegexp.java,v
retrieving revision 1.46
diff -b -u -r1.46 RubyRegexp.java
--- src/org/jruby/RubyRegexp.java	30 Apr 2006 14:59:24 -0000	1.46
+++ src/org/jruby/RubyRegexp.java	3 Jul 2006 04:08:49 -0000
@@ -134,6 +134,7 @@
         regexpClass.defineSingletonMethod("quote", callbackFactory.getSingletonMethod("quote", RubyString.class));
         regexpClass.defineSingletonMethod("escape", callbackFactory.getSingletonMethod("quote", RubyString.class));
         regexpClass.defineSingletonMethod("last_match", callbackFactory.getSingletonMethod("last_match_s"));
+        regexpClass.defineSingletonMethod("union", callbackFactory.getOptSingletonMethod("union"));
 
         return regexpClass;
     }
@@ -512,6 +513,9 @@
             if (RubyString.isAlnum(c)) {
                 sb.append(c);
             } else if (c == '/') {
+                if (i == 0 || regex.charAt(i - 1) != '\\') {
+                    sb.append("\\");
+                }
             	sb.append(c);
             } else if (RubyString.isPrint(c)) {
                 sb.append(c);
@@ -550,6 +554,34 @@
         return getRuntime().newString(sb.toString());
     }
     
+    /**
+     * rb_reg_s_union
+     */
+    public static IRubyObject union(IRubyObject recv, IRubyObject[] args) {
+        if (args.length == 0) {
+            return newInstance(recv, new IRubyObject[] {recv.getRuntime().newString("(?!)")});
+        } else if (args.length == 1) {
+            IRubyObject arg = args[0].convertToType("Regexp", "to_regexp", false);
+            if (!arg.isNil()) {
+                return arg;
+            }
+            return newInstance(recv, new IRubyObject[] {quote(recv, args[0].convertToString())});
+        } else {
+            StringBuffer sb = new StringBuffer();
+            for (int i = 0; i < args.length; i++) {
+                if (i > 0) {
+                    sb.append("|");
+                }
+                IRubyObject arg = args[i].convertToType("Regexp", "to_regexp", false);
+                if (arg.isNil()) {
+                    arg = quote(recv, args[i].convertToString());
+                }
+                sb.append(arg.toString());
+            }
+            return newInstance(recv, new IRubyObject[] {recv.getRuntime().newString(sb.toString())});
+        }
+    }
+
     
     public IRubyObject to_s() {
         return getRuntime().newString(toString());
@@ -570,7 +602,7 @@
 		}
 
     	buffer.append(':');
-    	buffer.append(pattern.pattern());
+        buffer.append(pattern.pattern().replaceAll("^/|([^\\\\])/", "$1\\\\/"));
 		buffer.append(')');
 
     	return buffer.toString();
Index: test/testRegexp.rb
===================================================================
RCS file: /cvsroot/jruby/jruby/test/testRegexp.rb,v
retrieving revision 1.13
diff -b -u -r1.13 testRegexp.rb
--- test/testRegexp.rb	23 Apr 2006 18:12:44 -0000	1.13
+++ test/testRegexp.rb	3 Jul 2006 04:08:50 -0000
@@ -65,9 +65,18 @@
 test_equal("^admin\\/.+$", re.source)
 test_equal("/^admin\\/.+$/", re.inspect)
 
+re = Regexp.new("/hi/")
+test_equal("/hi/", re.source)
+test_equal("/\\/hi\\//", re.inspect)
+
 ##### Posix sequences ######
 "a  b" =~ /([[:space:]]+)/
 test_equal("  ", $1)
 # We should only honor this as posix sequence inside [] (bug 1475096)
 #test_equal(0, "a  b" =~ /([:space:]+)/)
 
+##### union #####
+test_equal(/(?!)/, Regexp.union)
+test_equal(/penzance/, Regexp.union("penzance"))
+test_equal(/skiing|sledding/, Regexp.union("skiing", "sledding"))
+test_equal(/(?-mix:dogs)|(?i-mx:cats)/, Regexp.union(/dogs/, /cats/i))
