https://bugs.ruby-lang.org/
https://bugs.ruby-lang.org/favicon.ico?1711330511
2012-03-25T16:54:25Z
Ruby Issue Tracking System
Ruby master - Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
https://bugs.ruby-lang.org/issues/5007?journal_id=25150
2012-03-25T16:54:25Z
mame (Yusuke Endoh)
mame@ruby-lang.org
<ul><li><strong>Assignee</strong> set to <i>matz (Yukihiro Matsumoto)</i></li><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li></ul>
Ruby master - Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
https://bugs.ruby-lang.org/issues/5007?journal_id=25944
2012-04-17T04:08:16Z
trans (Thomas Sawyer)
<ul></ul><p>I don't see how this solves the case presented in <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Proc#+ (Rejected)" href="https://bugs.ruby-lang.org/issues/6298">#6298</a>.</p>
<p>Given:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">class</span> <span class="nc">BlockCollection</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="o">*</span><span class="n">procs</span><span class="p">)</span>
<span class="vi">@procs</span> <span class="o">=</span> <span class="n">procs</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">to_proc</span>
<span class="n">procs</span> <span class="o">=</span> <span class="vi">@procs</span>
<span class="no">Proc</span><span class="p">.</span><span class="nf">new</span><span class="p">{</span> <span class="o">|*</span><span class="n">a</span><span class="o">|</span> <span class="n">procs</span><span class="p">.</span><span class="nf">each</span><span class="p">{</span> <span class="o">|</span><span class="nb">p</span><span class="o">|</span> <span class="nb">p</span><span class="p">.</span><span class="nf">call_under</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="o">*</span><span class="n">a</span><span class="p">)</span> <span class="p">}</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>What is <code>self</code> here, or what should it be? Such that:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">module</span> <span class="nn">M</span>
<span class="no">A</span> <span class="o">=</span> <span class="no">Proc</span><span class="p">.</span><span class="nf">new</span><span class="p">{</span> <span class="nb">self</span> <span class="p">}</span>
<span class="k">end</span>
<span class="n">bc</span> <span class="o">=</span> <span class="no">BlockCollection</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">A</span><span class="p">)</span>
<span class="n">bc</span><span class="p">.</span><span class="nf">call</span> <span class="c1">#=> M</span>
<span class="s1">'F'</span><span class="p">.</span><span class="nf">instance_eval</span><span class="p">(</span><span class="o">&</span><span class="n">bc</span><span class="p">)</span> <span class="c1">#=> 'F'</span>
</code></pre>
Ruby master - Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
https://bugs.ruby-lang.org/issues/5007?journal_id=25973
2012-04-17T22:52:30Z
mame (Yusuke Endoh)
mame@ruby-lang.org
<ul><li><strong>File</strong> <a href="/attachments/2616">proc_call_under.patch</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/2616/proc_call_under.patch">proc_call_under.patch</a> added</li></ul><p>Hello,</p>
<p>I made a proof-of-concept patch.<br>
Not tested yet. Please try it and find a bug.<br>
It (and some related functions) seem to need some refactoring work<br>
because it calls directly invoke_block_from_c which is very internal<br>
function.</p>
<pre><code> $ ./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
</code></pre>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/proc.c b/proc.c
index d44e8d8..7ad490e 100644
</span><span class="gd">--- a/proc.c
</span><span class="gi">+++ b/proc.c
</span><span class="p">@@ -567,6 +567,22 @@</span> proc_call(int argc, VALUE *argv, VALUE procval)
return vret;
}
<span class="gi">+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);
+}
+
</span> #if SIZEOF_LONG > SIZEOF_INT
static inline int
check_argc(long argc)
<span class="p">@@ -2183,6 +2199,7 @@</span> 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);
<span class="gi">+ rb_define_method(rb_cProc, "call_under", proc_call_under, -1);
</span> #endif
rb_define_method(rb_cProc, "to_proc", proc_to_proc, 0);
rb_define_method(rb_cProc, "arity", proc_arity, 0);
<span class="gh">diff --git a/vm_eval.c b/vm_eval.c
index 6c26b97..562a215 100644
</span><span class="gd">--- a/vm_eval.c
</span><span class="gi">+++ b/vm_eval.c
</span><span class="p">@@ -1262,6 +1262,30 @@</span> yield_under(VALUE under, VALUE self, VALUE values)
}
}
<span class="gi">+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);
+}
+
</span> /* string eval under the class/module context */
static VALUE
eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line)
</code></pre>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@tsg.ne.jp" class="email">mame@tsg.ne.jp</a></p>
Ruby master - Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
https://bugs.ruby-lang.org/issues/5007?journal_id=33289
2012-11-20T22:34:28Z
mame (Yusuke Endoh)
mame@ruby-lang.org
<ul><li><strong>Target version</strong> set to <i>2.6</i></li></ul>
Ruby master - Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
https://bugs.ruby-lang.org/issues/5007?journal_id=40191
2013-06-29T06:18:16Z
judofyr (Magnus Holm)
judofyr@gmail.com
<ul></ul><p>I concur with trans: I don't think this issue will solve <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Proc#+ (Rejected)" href="https://bugs.ruby-lang.org/issues/6298">#6298</a>. However, please keep that discussion out of this issue.</p>
<p>Would it be possible to get a OK/NG for inclusion of this in 2.1?</p>
<p>Still not sure about the name. Maybe #call_with is better?</p>
Ruby master - Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
https://bugs.ruby-lang.org/issues/5007?journal_id=40193
2013-06-29T06:52:46Z
phluid61 (Matthew Kerwin)
matthew@kerwin.net.au
<ul></ul><p>judofyr (Magnus Holm) wrote:</p>
<blockquote>
<p>Still not sure about the name. Maybe #call_with is better?</p>
</blockquote>
<p>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.</p>
<p>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?</p>
Ruby master - Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
https://bugs.ruby-lang.org/issues/5007?journal_id=68698
2017-12-25T18:15:00Z
naruse (Yui NARUSE)
naruse@airemix.jp
<ul><li><strong>Target version</strong> deleted (<del><i>2.6</i></del>)</li></ul>
Ruby master - Feature #5007: Proc#call_under: Unifying instance_eval and instance_exec
https://bugs.ruby-lang.org/issues/5007?journal_id=71558
2018-04-19T07:57:49Z
nobu (Nobuyoshi Nakada)
nobu@ruby-lang.org
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/71558/diff?detail_id=48979">diff</a>)</li></ul>