Project

General

Profile

Feature #7883

Add Regex#to_proc

Added by Robert Klemme almost 4 years ago. Updated almost 2 years ago.

Status:
Open
Priority:
Normal
[ruby-core:52514]

Description

Just a small addition to the standard library:

class Regexp
  def to_proc; lambda {|s| self =~ s} end
end

With that one can use a Regexp everywhere a Proc is used as filtering criteria saving a bit of typing. While we have Enumerable#grep already there may be other cases where you want to do something like

irb(main):008:0> %w{foo bar baz}.select &/\Ab/
=> ["bar", "baz"]
irb(main):009:0> %w{foo bar baz}.reject &/\Ab/
=> ["foo"]
irb(main):010:0> %w{foo bar baz}.find &/\Ab/
=> "bar"

Note: line 9 and 10 are not possible with Enumerable#grep AFAIK.

I see low risk of breaking something.

History

#1 [ruby-core:52516] Updated by Nobuyoshi Nakada almost 4 years ago

You can use /\Ab/.method(:=~).

#2 [ruby-core:52517] Updated by Charlie Somerville almost 4 years ago

You can use /\Ab/.method(:=~).

This is more typing than just using '{ |x| x =~ /\Ab/ }'.

I like this idea, it's something I have to do quite often.

I've also wanted a 'grep_v' method before, but reject with Regexp#to_proc would suit perfectly.

#3 [ruby-core:52518] Updated by Alex Young almost 4 years ago

On 19/02/2013 07:58, rklemme (Robert Klemme) wrote:

Issue #7883 has been reported by rklemme (Robert Klemme).

Lovely. Definite +1 from me (for whatever that's worth).

--
Alex

#4 [ruby-core:52520] Updated by Robert Klemme almost 4 years ago

nobu (Nobuyoshi Nakada) wrote:

You can use /\Ab/.method(:=~).

Yes, but that's not the point. In that case I'd prefer the real block as Charlie suggested.

#5 [ruby-core:52528] Updated by Ilya Vorontsov almost 4 years ago

Cool idea. +1

#6 [ruby-core:52527] Updated by Magnus Holm almost 4 years ago

class Regexp
  def to_proc; lambda {|s| self =~ s} end
end

A more general case:

class Object
  def to_proc
    lambda { |other| self === other }
  end
end

(Not that I think this is going to be accepted…)

#7 [ruby-core:52535] Updated by Lee Jarvis almost 4 years ago

I like this, and I especially like the modified version from judofyr. You could also do ["abc", 3, "foo", etc].find(&Integer) which is neat, but maybe that's a push in the wrong direction, I'm not sure.

#8 [ruby-core:52624] Updated by Gosha Arinich almost 4 years ago

Nice one, +1 on it as well.

#9 [ruby-core:52625] Updated by jy j almost 4 years ago

judofyr (Magnus Holm) wrote:

class Regexp
  def to_proc; lambda {|s| self =~ s} end
end

A more general case:

class Object
  def to_proc
    lambda { |other| self === other }
  end
end

(Not that I think this is going to be accepted…)

cool!

#10 [ruby-core:52647] Updated by Koichi Sasada almost 4 years ago

  • Assignee set to Yukihiro Matsumoto
  • Target version changed from 1.9.3 to next minor

#11 [ruby-core:67047] Updated by Robert Klemme almost 2 years ago

Was any of the two suggested forms ever realized?

#12 [ruby-core:67057] Updated by Nobuyoshi Nakada almost 2 years ago

  • Description updated (diff)

Nothing, and line 10 is possible with grep

%w{foo bar baz}.grep(/\Ab/) {|s|break s}

Anyway, a patch.

diff --git i/re.c w/re.c
index 1a0f0b1..d345f17 100644
--- i/re.c
+++ w/re.c
@@ -801,6 +801,19 @@ rb_reg_named_captures(VALUE re)
     return hash;
 }

+static VALUE
+rb_reg_to_proc(VALUE re)
+{
+    const ID id = 1;
+    VALUE proc = rb_attr_get(re, id);
+    if (NIL_P(proc)) {
+   proc = rb_obj_method(re, ID2SYM(rb_intern("=~")));
+   proc = rb_funcall(proc, rb_intern("to_proc"), 0, 0);
+   rb_ivar_set(re, id, proc);
+    }
+    return proc;
+}
+
 static int
 onig_new_with_source(regex_t** reg, const UChar* pattern, const UChar* pattern_end,
      OnigOptionType option, OnigEncoding enc, const OnigSyntaxType* syntax,
@@ -3660,6 +3673,7 @@ Init_Regexp(void)
     rb_define_method(rb_cRegexp, "fixed_encoding?", rb_reg_fixed_encoding_p, 0);
     rb_define_method(rb_cRegexp, "names", rb_reg_names, 0);
     rb_define_method(rb_cRegexp, "named_captures", rb_reg_named_captures, 0);
+    rb_define_method(rb_cRegexp, "to_proc", rb_reg_to_proc, 0);

     /* see Regexp.options and Regexp.new */
     rb_define_const(rb_cRegexp, "IGNORECASE", INT2FIX(ONIG_OPTION_IGNORECASE));

#13 [ruby-core:67067] Updated by Robert Klemme almost 2 years ago

Nobuyoshi Nakada wrote:

Nothing, and line 10 is possible with grep

%w{foo bar baz}.grep(/\Ab/) {|s|break s}

Yes, but a bit lengthy.

Anyway, a patch.

Cool! Thanks a lot!

#14 [ruby-core:67084] Updated by Tsuyoshi Sawada almost 2 years ago

If the proposed patch to issue #9602 gets accepted, then that will covert this issue in a more general way.

Also available in: Atom PDF