Project

General

Profile

Actions

Feature #7883

open

Add Regex#to_proc

Added by rklemme (Robert Klemme) over 11 years ago. Updated 7 months ago.

Status:
Assigned
Target version:
-
[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.

Updated by nobu (Nobuyoshi Nakada) over 11 years ago

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

Updated by Anonymous over 11 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.

Updated by regularfry (Alex Young) over 11 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

Updated by rklemme (Robert Klemme) over 11 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.

Updated by judofyr (Magnus Holm) over 11 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…)

Updated by injekt (Lee Jarvis) over 11 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.

Updated by goshakkk (Gosha Arinich) over 11 years ago

Nice one, +1 on it as well.

Updated by jjyr (Jinyang Jiang) over 11 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!

Updated by ko1 (Koichi Sasada) over 11 years ago

  • Assignee set to matz (Yukihiro Matsumoto)
  • Target version changed from 1.9.3 to 2.6

Updated by rklemme (Robert Klemme) almost 10 years ago

Was any of the two suggested forms ever realized?

Updated by nobu (Nobuyoshi Nakada) almost 10 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));

Updated by rklemme (Robert Klemme) almost 10 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!

Updated by sawa (Tsuyoshi Sawada) almost 10 years ago

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

Actions #15

Updated by naruse (Yui NARUSE) almost 7 years ago

  • Target version deleted (2.6)
Actions #16

Updated by hsbt (Hiroshi SHIBATA) 7 months ago

  • Status changed from Open to Assigned
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0