vm_eval.c: rb_current_receiver

* vm_eval.c (rb_current_receiver): new function to return the
  receiver in the current control frame.  [Feature #10195]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48462 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2014-11-16 10:38:15 +00:00
Родитель b1acfbc121
Коммит de870875f7
6 изменённых файлов: 38 добавлений и 0 удалений

Просмотреть файл

@ -1,3 +1,8 @@
Sun Nov 16 19:38:10 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* vm_eval.c (rb_current_receiver): new function to return the
receiver in the current control frame. [Feature #10195]
Sun Nov 16 19:11:04 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/timeout.rb (Timeout::ExitException#exception): rescue

Просмотреть файл

@ -442,6 +442,11 @@ you may rely on:
VALUE rb_call_super(int argc, const VALUE *argv)
To achieve the receiver of the current scope (if no other way is
available), you can use:
VALUE rb_current_receiver(void)
=== Constant Definition
We have 2 functions to define constants:

Просмотреть файл

@ -473,6 +473,17 @@ funcはクラスを引数として受け取って新しく割り当てられ
ソースなどを含まない,できるだけ「空」のままにしておいたほう
がよいでしょう.
継承したクラスにある既存のメソッドをオーバーライドしているな
ら,オーバーライドされたメソッドを呼び出すには以下の関数を使
います.
VALUE rb_call_super(int argc, const VALUE *argv)
現在のスコープのレシーバは(他に方法がなければ),以下の関数で
得ることができます.
VALUE rb_current_receiver(void)
=== 定数定義
拡張ライブラリが必要な定数はあらかじめ定義しておいた方が良い

Просмотреть файл

@ -1474,6 +1474,7 @@ VALUE rb_funcall_passing_block(VALUE, ID, int, const VALUE*);
VALUE rb_funcall_with_block(VALUE, ID, int, const VALUE*, VALUE);
int rb_scan_args(int, const VALUE*, const char*, ...);
VALUE rb_call_super(int, const VALUE*);
VALUE rb_current_receiver(void);
/* rb_scan_args() format allows ':' for optional hash */
#define HAVE_RB_SCAN_ARGS_OPTIONAL_HASH 1

Просмотреть файл

@ -15,6 +15,7 @@ class TestProc::TestBMethod
class Bound < Base
define_method(:foo, Bug::Proc.make_call_super(42))
define_method(:receiver, Bug::Proc.make_call_receiver(nil))
end
def test_super_in_bmethod
@ -28,4 +29,9 @@ class TestProc::TestBMethod
obj.foo(2) {|*a| result = a}
assert_equal([2, 42], result)
end
def test_receiver_in_bmethod
obj = Bound.new
assert_same(obj, obj.receiver)
end
end

Просмотреть файл

@ -290,6 +290,16 @@ rb_call_super(int argc, const VALUE *argv)
return vm_call_super(GET_THREAD(), argc, argv);
}
VALUE
rb_current_receiver(void)
{
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp;
if (!th || !(cfp = th->cfp))
rb_raise(rb_eRuntimeError, "no self, no life");
return cfp->self;
}
static inline void
stack_check(void)
{