ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:37924] [Ruby 1.9 - Feature #5007][Open] Proc#call_under: Unifying instance_eval and instance_exec
@ 2011-07-09 14:26 Magnus Holm
  2012-03-25  7:54 ` [ruby-core:43650] [ruby-trunk - Feature #5007][Assigned] " mame (Yusuke Endoh)
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Magnus Holm @ 2011-07-09 14:26 UTC (permalink / raw
  To: ruby-core


Issue #5007 has been reported by Magnus Holm.

----------------------------------------
Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
http://redmine.ruby-lang.org/issues/5007

Author: Magnus Holm
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 


I'm proposing a method called Proc#call_under (the name could be
discussed) which both unifies instance_eval and instance_exec, and makes
it possible to call a Proc with a block and a scope:

  Proc#call_under(self, *args, &blk):

    proc { self }.call_under(1) # => 1

    proc { |a| self + a }.call_under(1, 2) # => 3

    proc { |&b| self + b.call }.call_under(2) { 2 } # => 4


-- 
http://redmine.ruby-lang.org

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:43650] [ruby-trunk - Feature #5007][Assigned] Proc#call_under: Unifying instance_eval and instance_exec
  2011-07-09 14:26 [ruby-core:37924] [Ruby 1.9 - Feature #5007][Open] Proc#call_under: Unifying instance_eval and instance_exec Magnus Holm
@ 2012-03-25  7:54 ` mame (Yusuke Endoh)
  2012-04-16 19:08 ` [ruby-core:44394] [ruby-trunk - Feature #5007] " trans (Thomas Sawyer)
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: mame (Yusuke Endoh) @ 2012-03-25  7:54 UTC (permalink / raw
  To: ruby-core


Issue #5007 has been updated by mame (Yusuke Endoh).

Status changed from Open to Assigned
Assignee set to matz (Yukihiro Matsumoto)


----------------------------------------
Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
https://bugs.ruby-lang.org/issues/5007#change-25150

Author: judofyr (Magnus Holm)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: 
Target version: 


I'm proposing a method called Proc#call_under (the name could be
discussed) which both unifies instance_eval and instance_exec, and makes
it possible to call a Proc with a block and a scope:

  Proc#call_under(self, *args, &blk):

    proc { self }.call_under(1) # => 1

    proc { |a| self + a }.call_under(1, 2) # => 3

    proc { |&b| self + b.call }.call_under(2) { 2 } # => 4


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:44394] [ruby-trunk - Feature #5007] Proc#call_under: Unifying instance_eval and instance_exec
  2011-07-09 14:26 [ruby-core:37924] [Ruby 1.9 - Feature #5007][Open] Proc#call_under: Unifying instance_eval and instance_exec Magnus Holm
  2012-03-25  7:54 ` [ruby-core:43650] [ruby-trunk - Feature #5007][Assigned] " mame (Yusuke Endoh)
@ 2012-04-16 19:08 ` trans (Thomas Sawyer)
  2012-04-17 13:53 ` [ruby-core:44422] " mame (Yusuke Endoh)
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: trans (Thomas Sawyer) @ 2012-04-16 19:08 UTC (permalink / raw
  To: ruby-core


Issue #5007 has been updated by trans (Thomas Sawyer).


=begin
I don't see how this solves the case presented in #6298.

Given:

  class BlockCollection
    def initialize(*procs)
      @procs = procs
    end
    def to_proc
      procs = @procs
      Proc.new{ |*a| procs.each{ |p| p.call_under(self, *a) } }
    end
  end

What is `self` here, or what should it be? Such that:

  module M
    A = Proc.new{ self }
  end

  bc = BlockCollection.new(A)

  bc.call  #=> M

  'F'.instance_eval(&bc)  #=> 'F'

=end

----------------------------------------
Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
https://bugs.ruby-lang.org/issues/5007#change-25944

Author: judofyr (Magnus Holm)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: 
Target version: 


I'm proposing a method called Proc#call_under (the name could be
discussed) which both unifies instance_eval and instance_exec, and makes
it possible to call a Proc with a block and a scope:

  Proc#call_under(self, *args, &blk):

    proc { self }.call_under(1) # => 1

    proc { |a| self + a }.call_under(1, 2) # => 3

    proc { |&b| self + b.call }.call_under(2) { 2 } # => 4


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:44422] [ruby-trunk - Feature #5007] Proc#call_under: Unifying instance_eval and instance_exec
  2011-07-09 14:26 [ruby-core:37924] [Ruby 1.9 - Feature #5007][Open] Proc#call_under: Unifying instance_eval and instance_exec Magnus Holm
  2012-03-25  7:54 ` [ruby-core:43650] [ruby-trunk - Feature #5007][Assigned] " mame (Yusuke Endoh)
  2012-04-16 19:08 ` [ruby-core:44394] [ruby-trunk - Feature #5007] " trans (Thomas Sawyer)
@ 2012-04-17 13:53 ` mame (Yusuke Endoh)
  2013-06-28 21:18 ` [ruby-core:55692] " judofyr (Magnus Holm)
  2013-06-28 21:52 ` [ruby-core:55694] " phluid61 (Matthew Kerwin)
  4 siblings, 0 replies; 6+ messages in thread
From: mame (Yusuke Endoh) @ 2012-04-17 13:53 UTC (permalink / raw
  To: ruby-core


Issue #5007 has been updated by mame (Yusuke Endoh).

File proc_call_under.patch added

Hello,

I made a proof-of-concept patch.
Not tested yet.  Please try it and find a bug.
It (and some related functions) seem to need some refactoring work
because it calls directly invoke_block_from_c which is very internal
function.

  $ ./miniruby -e '
    p proc { self }.call_under(1)
    p proc { |a| self + a }.call_under(1, 2)
    p proc { |&b| self + b.call }.call_under(2) { 2 }
  '
  1
  3
  4


diff --git a/proc.c b/proc.c
index d44e8d8..7ad490e 100644
--- a/proc.c
+++ b/proc.c
@@ -567,6 +567,22 @@ proc_call(int argc, VALUE *argv, VALUE procval)
     return vret;
 }
 
+VALUE rb_proc_call_under(VALUE procval, VALUE under, VALUE self, VALUE values);
+
+static VALUE
+proc_call_under(int argc, VALUE *argv, VALUE procval)
+{
+    VALUE self, klass, values;
+    rb_scan_args(argc, argv, "1*", &self, &values);
+    if (SPECIAL_CONST_P(self)) {
+	klass = Qnil;
+    }
+    else {
+	klass = rb_singleton_class(self);
+    }
+    return rb_proc_call_under(procval, klass, self, values);
+}
+
 #if SIZEOF_LONG > SIZEOF_INT
 static inline int
 check_argc(long argc)
@@ -2183,6 +2199,7 @@ Init_Proc(void)
     rb_define_method(rb_cProc, "[]", proc_call, -1);
     rb_define_method(rb_cProc, "===", proc_call, -1);
     rb_define_method(rb_cProc, "yield", proc_call, -1);
+    rb_define_method(rb_cProc, "call_under", proc_call_under, -1);
 #endif
     rb_define_method(rb_cProc, "to_proc", proc_to_proc, 0);
     rb_define_method(rb_cProc, "arity", proc_arity, 0);
diff --git a/vm_eval.c b/vm_eval.c
index 6c26b97..562a215 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -1262,6 +1262,30 @@ yield_under(VALUE under, VALUE self, VALUE values)
     }
 }
 
+static inline VALUE
+invoke_block_from_c(rb_thread_t *th, const rb_block_t *block,
+		    VALUE self, int argc, const VALUE *argv,
+		    const rb_block_t *blockptr, const NODE *cref);
+
+VALUE
+rb_proc_call_under(VALUE procval, VALUE under, VALUE self, VALUE values)
+{
+    rb_thread_t *th = GET_THREAD();
+    rb_block_t block;
+    NODE *cref;
+    rb_proc_t *proc;
+
+    GetProcPtr(procval, proc);
+    block = proc->block;
+    block.self = self;
+    cref = vm_cref_push(th, under, NOEX_PUBLIC, &proc->block);
+    cref->flags |= NODE_FL_CREF_PUSHED_BY_EVAL;
+
+    return invoke_block_from_c(th, &block, self,
+	    RARRAY_LENINT(values), RARRAY_PTR(values),
+	    GC_GUARDED_PTR_REF(th->cfp->lfp[0]), cref);
+}
+
 /* string eval under the class/module context */
 static VALUE
 eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line)

-- 
Yusuke Endoh <mame@tsg.ne.jp>
----------------------------------------
Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
https://bugs.ruby-lang.org/issues/5007#change-25973

Author: judofyr (Magnus Holm)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: 
Target version: 


I'm proposing a method called Proc#call_under (the name could be
discussed) which both unifies instance_eval and instance_exec, and makes
it possible to call a Proc with a block and a scope:

  Proc#call_under(self, *args, &blk):

    proc { self }.call_under(1) # => 1

    proc { |a| self + a }.call_under(1, 2) # => 3

    proc { |&b| self + b.call }.call_under(2) { 2 } # => 4


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [ruby-core:55692] [ruby-trunk - Feature #5007] Proc#call_under: Unifying instance_eval and instance_exec
  2011-07-09 14:26 [ruby-core:37924] [Ruby 1.9 - Feature #5007][Open] Proc#call_under: Unifying instance_eval and instance_exec Magnus Holm
                   ` (2 preceding siblings ...)
  2012-04-17 13:53 ` [ruby-core:44422] " mame (Yusuke Endoh)
@ 2013-06-28 21:18 ` judofyr (Magnus Holm)
  2013-06-28 21:52 ` [ruby-core:55694] " phluid61 (Matthew Kerwin)
  4 siblings, 0 replies; 6+ messages in thread
From: judofyr (Magnus Holm) @ 2013-06-28 21:18 UTC (permalink / raw
  To: ruby-core


Issue #5007 has been updated by judofyr (Magnus Holm).


I concur with trans: I don't think this issue will solve #6298. However, please keep that discussion out of this issue.

Would it be possible to get a OK/NG for inclusion of this in 2.1?

Still not sure about the name. Maybe #call_with is better?
----------------------------------------
Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
https://bugs.ruby-lang.org/issues/5007#change-40191

Author: judofyr (Magnus Holm)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: 
Target version: next minor


I'm proposing a method called Proc#call_under (the name could be
discussed) which both unifies instance_eval and instance_exec, and makes
it possible to call a Proc with a block and a scope:

  Proc#call_under(self, *args, &blk):

    proc { self }.call_under(1) # => 1

    proc { |a| self + a }.call_under(1, 2) # => 3

    proc { |&b| self + b.call }.call_under(2) { 2 } # => 4


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:55694] [ruby-trunk - Feature #5007] Proc#call_under: Unifying instance_eval and instance_exec
  2011-07-09 14:26 [ruby-core:37924] [Ruby 1.9 - Feature #5007][Open] Proc#call_under: Unifying instance_eval and instance_exec Magnus Holm
                   ` (3 preceding siblings ...)
  2013-06-28 21:18 ` [ruby-core:55692] " judofyr (Magnus Holm)
@ 2013-06-28 21:52 ` phluid61 (Matthew Kerwin)
  4 siblings, 0 replies; 6+ messages in thread
From: phluid61 (Matthew Kerwin) @ 2013-06-28 21:52 UTC (permalink / raw
  To: ruby-core


Issue #5007 has been updated by phluid61 (Matthew Kerwin).


judofyr (Magnus Holm) wrote:
> Still not sure about the name. Maybe #call_with is better?

I suggest #call_as or #call_bound: "as" because it suggests that "self" in the proc will refer to the first parameter, or possibly "bound" because we're binding the proc to the object (as well as to its existing binding scope).  However I don't have strong feelings about any name, except that I like #call_with less than any others.

A side discussion: how does this tie in with currying?  For example, do you foresee a Proc#curry_under (or curry_self, or curry_with, or whatever) method, that would cause the proc to be passed to instance_exec when all its parameters are satisfied?
----------------------------------------
Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
https://bugs.ruby-lang.org/issues/5007#change-40193

Author: judofyr (Magnus Holm)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: 
Target version: next minor


I'm proposing a method called Proc#call_under (the name could be
discussed) which both unifies instance_eval and instance_exec, and makes
it possible to call a Proc with a block and a scope:

  Proc#call_under(self, *args, &blk):

    proc { self }.call_under(1) # => 1

    proc { |a| self + a }.call_under(1, 2) # => 3

    proc { |&b| self + b.call }.call_under(2) { 2 } # => 4


-- 
http://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-06-28 22:19 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-09 14:26 [ruby-core:37924] [Ruby 1.9 - Feature #5007][Open] Proc#call_under: Unifying instance_eval and instance_exec Magnus Holm
2012-03-25  7:54 ` [ruby-core:43650] [ruby-trunk - Feature #5007][Assigned] " mame (Yusuke Endoh)
2012-04-16 19:08 ` [ruby-core:44394] [ruby-trunk - Feature #5007] " trans (Thomas Sawyer)
2012-04-17 13:53 ` [ruby-core:44422] " mame (Yusuke Endoh)
2013-06-28 21:18 ` [ruby-core:55692] " judofyr (Magnus Holm)
2013-06-28 21:52 ` [ruby-core:55694] " phluid61 (Matthew Kerwin)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).