Project

General

Profile

Actions

Feature #7883

open

Add Regex#to_proc

Added by rklemme (Robert Klemme) about 11 years ago. Updated about 6 years ago.

Status:
Open
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) about 11 years ago

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

Updated by Anonymous about 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) about 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) about 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) about 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) about 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) about 11 years ago

Nice one, +1 on it as well.

Updated by jjyr (Jinyang Jiang) about 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) about 11 years ago

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

Updated by rklemme (Robert Klemme) about 9 years ago

Was any of the two suggested forms ever realized?

Updated by nobu (Nobuyoshi Nakada) about 9 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) about 9 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) about 9 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) about 6 years ago

  • Target version deleted (2.6)
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0