メソッドとレシーバの組み合わせのオブジェクト。Method.new
ではなく Object#method
で作成する。
Methd#call
メソッドで呼び出しできる。ruby-1.1b9_01
と初期からある。
$ docker run -it --rm rubylang/all-ruby ./all-ruby -e 'p Method'
...
ruby-1.1b9 -e:1: Uninitialized constant Method (NameError)
exit 1
ruby-1.1b9_01 Method
...
ruby-3.4.1 Method
$ docker run -it --rm rubylang/all-ruby ./all-ruby -e 'p "a".method(:to_s)'
...
ruby-1.1b9 -e:1: undefined method `method' for "a" (NameError)
exit 1
ruby-1.1b9_01 #<Method: String#to_s>
...
ruby-1.4.6 #<Method: String#to_s>
ruby-1.6.0 #<Method: String(String)#to_s>
...
ruby-1.6.8 #<Method: String(String)#to_s>
ruby-1.8.0 #<Method: String#to_s>
...
ruby-2.7.0-preview2 #<Method: String#to_s>
ruby-2.7.0-preview3 #<Method: String#to_s()>
...
ruby-3.4.1 #<Method: String#to_s()>
メソッドオブジェクト。UnboundMethod.new
ではなく Module#instance_method
などで作成する。
UnboundMethd#bind
で Method
を作成しないと呼び出しできない。ruby-1.6.0
からある。
$ docker run -it --rm rubylang/all-ruby ./all-ruby -e 'p UnboundMethod'
...
ruby-1.4.6 /tmp/rb8oZM7a:1: uninitialized constant UnboundMethod (NameError)
exit 1
ruby-1.6.0 UnboundMethod
...
ruby-3.4.1 UnboundMethod
$ docker run -it --rm rubylang/all-ruby ./all-ruby -e 'p String.instance_method(:to_s)'
...
ruby-1.4.6 /tmp/rbfTqSUb:1: undefined method `instance_method' for String:Class (NameError)
exit 1
ruby-1.6.0 #<UnboundMethod: String(String)#to_s>
...
ruby-1.6.8 #<UnboundMethod: String(String)#to_s>
ruby-1.8.0 #<UnboundMethod: String#to_s>
...
ruby-2.7.0-preview2 #<UnboundMethod: String#to_s>
ruby-2.7.0-preview3 #<UnboundMethod: String#to_s()>
...
ruby-3.4.1 #<UnboundMethod: String#to_s()>
Method
および nboundMethod
の中身の C 構造体。変遷を確認するためスクリプトを用意した。
require "time"
commit = "HEAD"
loop do
$stderr.puts
commit=`git log -n1 --format=%h #{commit}~`.chomp
file = `git grep --name-only "^struct METHOD {" #{commit}`[/^[0-9a-f]*:(.*)/, 1]
break unless file
struct_def = `git blame --no-progress #{commit} #{file}`.gsub(/\r\n/, "\n")[/.*\) struct METHOD {(?:\n.*)*?\n.*\) \};$/]
t = Time.at(0)
struct_def.each_line do |l|
l =~ /^([0-9a-f]+) \(.* ([-0-9]+ [:0-9]+ [+0-9]+) +[0-9]+\) (.*)/
hash, timestr, line = $1, $2, $3
time = Time.parse(timestr)
if time > t
t = time
commit = hash
end
end
tag = `git tag --contains #{commit}`.lines.grep(/^v/).min.chomp
puts "#{commit}(#{tag}):#{file}", struct_def
if system("git notes --ref ruby-trunk-changes show #{commit} >/dev/null")
rev = `git log -n1 #{commit}`[/ *git-svn-id:.*@([0-9]*)/, 1]
search = rev ? "r#{rev}" : commit
puts "https://ruby-trunk-changes.hatenablog.com/search?q=#{search}"
end
end
実行結果は以下の通り。
$ ruby history.rb
6b7d32a5e54(v3_2_0):proc.c
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 29) struct METHOD {
5e8a147480f (Koichi Sasada 2015-07-03 11:24:50 +0000 30) const VALUE recv;
5e8a147480f (Koichi Sasada 2015-07-03 11:24:50 +0000 31) const VALUE klass;
6b7d32a5e54 (Benoit Daloze 2022-09-28 19:49:13 +0200 32) /* needed for #super_method */
a15028bc38a (Nobuyoshi Nakada 2017-10-06 05:55:11 +0000 33) const VALUE iclass;
6b7d32a5e54 (Benoit Daloze 2022-09-28 19:49:13 +0200 34) /* Different than me->owner only for ZSUPER methods.
6b7d32a5e54 (Benoit Daloze 2022-09-28 19:49:13 +0200 35) This is error-prone but unavoidable unless ZSUPER methods are removed. */
6b7d32a5e54 (Benoit Daloze 2022-09-28 19:49:13 +0200 36) const VALUE owner;
5e8a147480f (Koichi Sasada 2015-07-03 11:24:50 +0000 37) const rb_method_entry_t * const me;
5e8a147480f (Koichi Sasada 2015-07-03 11:24:50 +0000 38) /* for bound methods, `me' should be rb_callable_method_entry_t * */
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 39) };
https://ruby-trunk-changes.hatenablog.com/search?q=6b7d32a5e54
a15028bc38a(v2_5_0):proc.c
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 37) struct METHOD {
5e8a147480f (Koichi Sasada 2015-07-03 11:24:50 +0000 38) const VALUE recv;
5e8a147480f (Koichi Sasada 2015-07-03 11:24:50 +0000 39) const VALUE klass;
a15028bc38a (Nobuyoshi Nakada 2017-10-06 05:55:11 +0000 40) const VALUE iclass;
5e8a147480f (Koichi Sasada 2015-07-03 11:24:50 +0000 41) const rb_method_entry_t * const me;
5e8a147480f (Koichi Sasada 2015-07-03 11:24:50 +0000 42) /* for bound methods, `me' should be rb_callable_method_entry_t * */
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 43) };
https://ruby-trunk-changes.hatenablog.com/search?q=r60127
5e8a147480f(v2_3_0):proc.c
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 29) struct METHOD {
5e8a147480f (Koichi Sasada 2015-07-03 11:24:50 +0000 30) const VALUE recv;
5e8a147480f (Koichi Sasada 2015-07-03 11:24:50 +0000 31) const VALUE klass;
5e8a147480f (Koichi Sasada 2015-07-03 11:24:50 +0000 32) const rb_method_entry_t * const me;
5e8a147480f (Koichi Sasada 2015-07-03 11:24:50 +0000 33) /* for bound methods, `me' should be rb_callable_method_entry_t * */
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 34) };
https://ruby-trunk-changes.hatenablog.com/search?q=r51126
57b817f4c55(v2_3_0):proc.c
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 23) struct METHOD {
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 24) VALUE recv;
c330876d7c5 (Koichi Sasada 2009-07-15 14:59:41 +0000 25) VALUE rclass;
319088e9c7a (Shugo Maeda 2012-08-02 11:08:44 +0000 26) VALUE defined_class;
c330876d7c5 (Koichi Sasada 2009-07-15 14:59:41 +0000 27) ID id;
57b817f4c55 (Koichi Sasada 2015-06-02 04:20:30 +0000 28) rb_method_entry_t * const me;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 29) };
https://ruby-trunk-changes.hatenablog.com/search?q=r50728
319088e9c7a(v2_0_0_0):proc.c
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 19) struct METHOD {
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 20) VALUE recv;
c330876d7c5 (Koichi Sasada 2009-07-15 14:59:41 +0000 21) VALUE rclass;
319088e9c7a (Shugo Maeda 2012-08-02 11:08:44 +0000 22) VALUE defined_class;
c330876d7c5 (Koichi Sasada 2009-07-15 14:59:41 +0000 23) ID id;
9a27239558d (Yusuke Endoh 2011-07-25 14:29:28 +0000 24) rb_method_entry_t *me;
da5b7f9229f (Yusuke Endoh 2011-07-25 15:17:56 +0000 25) struct unlinked_method_entry_list_entry *ume;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 26) };
https://ruby-trunk-changes.hatenablog.com/search?q=r36595
da5b7f9229f(v2_0_0_0):proc.c
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 17) struct METHOD {
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 18) VALUE recv;
c330876d7c5 (Koichi Sasada 2009-07-15 14:59:41 +0000 19) VALUE rclass;
c330876d7c5 (Koichi Sasada 2009-07-15 14:59:41 +0000 20) ID id;
9a27239558d (Yusuke Endoh 2011-07-25 14:29:28 +0000 21) rb_method_entry_t *me;
da5b7f9229f (Yusuke Endoh 2011-07-25 15:17:56 +0000 22) struct unlinked_method_entry_list_entry *ume;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 23) };
https://ruby-trunk-changes.hatenablog.com/search?q=r32671
9a27239558d(v2_0_0_0):proc.c
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 17) struct METHOD {
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 18) VALUE recv;
c330876d7c5 (Koichi Sasada 2009-07-15 14:59:41 +0000 19) VALUE rclass;
c330876d7c5 (Koichi Sasada 2009-07-15 14:59:41 +0000 20) ID id;
9a27239558d (Yusuke Endoh 2011-07-25 14:29:28 +0000 21) rb_method_entry_t *me;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 22) };
https://ruby-trunk-changes.hatenablog.com/search?q=r32669
fcf88c1b8df(v1_9_2_0):proc.c
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 17) struct METHOD {
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 18) VALUE recv;
c330876d7c5 (Koichi Sasada 2009-07-15 14:59:41 +0000 19) VALUE rclass;
c330876d7c5 (Koichi Sasada 2009-07-15 14:59:41 +0000 20) ID id;
fcf88c1b8df (Nobuyoshi Nakada 2009-08-28 02:45:41 +0000 21) rb_method_entry_t me;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 22) };
error: no note found for object fcf88c1b8df49ba0c4db026f2b17066ea66d3de2.
c330876d7c5(v1_9_2_0):proc.c
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 15) struct METHOD {
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 16) VALUE recv;
c330876d7c5 (Koichi Sasada 2009-07-15 14:59:41 +0000 17) VALUE rclass;
c330876d7c5 (Koichi Sasada 2009-07-15 14:59:41 +0000 18) ID id;
c330876d7c5 (Koichi Sasada 2009-07-15 14:59:41 +0000 19) rb_method_entry_t *me;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 20) };
error: no note found for object c330876d7c5065f89234becc5125426d0d136bdc.
87ea50380d0(v1_9_0_1):proc.c
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 15) struct METHOD {
c227d3feb39 (Yukihiro "Matz" Matsumoto 2007-11-22 01:17:52 +0000 16) VALUE oclass; /* class that holds the method */
87ea50380d0 (Tanaka Akira 2008-02-09 09:49:31 +0000 17) VALUE rclass; /* class of the receiver */
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 18) VALUE recv;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 19) ID id, oid;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 20) NODE *body;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 21) };
error: no note found for object 87ea50380d06e71889251a22e86731c7f1dfa6bb.
c227d3feb39(v1_9_0_0):proc.c
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 15) struct METHOD {
c227d3feb39 (Yukihiro "Matz" Matsumoto 2007-11-22 01:17:52 +0000 16) VALUE oclass; /* class that holds the method */
c227d3feb39 (Yukihiro "Matz" Matsumoto 2007-11-22 01:17:52 +0000 17) VALUE rclass; /* class of the recevier */
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 18) VALUE recv;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 19) ID id, oid;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 20) NODE *body;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 21) };
error: no note found for object c227d3feb393c7aaa4e40612dc1ac39e598df3b4.
c1f5d227197(v1_9_0_0):proc.c
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 16) struct METHOD {
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 17) VALUE klass, rklass;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 18) VALUE recv;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 19) ID id, oid;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 20) NODE *body;
c1f5d227197 (Nobuyoshi Nakada 2007-02-02 15:21:41 +0000 21) };
error: no note found for object c1f5d2271974b3b36a472a3af3c2acd275c69a65.
dbee6786307(v1_9_0_0):proc.c
dbee6786307 (Koichi Sasada 2007-01-17 08:48:52 +0000 16) struct METHOD {
dbee6786307 (Koichi Sasada 2007-01-17 08:48:52 +0000 17) VALUE klass, rklass;
dbee6786307 (Koichi Sasada 2007-01-17 08:48:52 +0000 18) VALUE recv;
dbee6786307 (Koichi Sasada 2007-01-17 08:48:52 +0000 19) ID id, oid;
dbee6786307 (Koichi Sasada 2007-01-17 08:48:52 +0000 20) NODE *body;
dbee6786307 (Koichi Sasada 2007-01-17 08:48:52 +0000 21) };
error: no note found for object dbee678630736a5d873cde1f262bf2cfc87e8dfe.
a3e1b1ce7ed(v1_9_0_0):eval_proc.c
a3e1b1ce7ed (Koichi Sasada 2006-12-31 15:02:22 +0000 7) struct METHOD {
a3e1b1ce7ed (Koichi Sasada 2006-12-31 15:02:22 +0000 8) VALUE klass, rklass;
a3e1b1ce7ed (Koichi Sasada 2006-12-31 15:02:22 +0000 9) VALUE recv;
a3e1b1ce7ed (Koichi Sasada 2006-12-31 15:02:22 +0000 10) ID id, oid;
a3e1b1ce7ed (Koichi Sasada 2006-12-31 15:02:22 +0000 11) NODE *body;
a3e1b1ce7ed (Koichi Sasada 2006-12-31 15:02:22 +0000 12) };
error: no note found for object a3e1b1ce7ed7e7ffac23015fc2fde56511b30681.
5b014a7427e(v1_9_0_0):env.h
5b014a7427e (Yukihiro "Matz" Matsumoto 2005-10-21 09:00:02 +0000 59) struct METHOD {
5b014a7427e (Yukihiro "Matz" Matsumoto 2005-10-21 09:00:02 +0000 60) VALUE klass, rklass;
5b014a7427e (Yukihiro "Matz" Matsumoto 2005-10-21 09:00:02 +0000 61) VALUE recv;
5b014a7427e (Yukihiro "Matz" Matsumoto 2005-10-21 09:00:02 +0000 62) ID id, oid;
5b014a7427e (Yukihiro "Matz" Matsumoto 2005-10-21 09:00:02 +0000 63) int safe_level;
5b014a7427e (Yukihiro "Matz" Matsumoto 2005-10-21 09:00:02 +0000 64) struct RNode *body;
5b014a7427e (Yukihiro "Matz" Matsumoto 2005-10-21 09:00:02 +0000 65) };
error: no note found for object 5b014a7427ef87fecb54c368cf3fe1efabb03f03.
17957e0dfca(v1_9_0_0):eval.c
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 8548) struct METHOD {
a7a7324ea64 (Yukihiro "Matz" Matsumoto 2002-01-18 14:24:01 +0000 8549) VALUE klass, rklass;
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 8550) VALUE recv;
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 8551) ID id, oid;
17957e0dfca (Yukihiro "Matz" Matsumoto 2005-08-16 15:24:15 +0000 8552) int safe_level;
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 8553) NODE *body;
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 8554) };
error: no note found for object 17957e0dfca25957556bdccd3590be9b9dee5923.
a7a7324ea64(v1_1_8):eval.c
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 8913) struct METHOD {
a7a7324ea64 (Yukihiro "Matz" Matsumoto 2002-01-18 14:24:01 +0000 8914) VALUE klass, rklass;
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 8915) VALUE recv;
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 8916) ID id, oid;
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 8917) NODE *body;
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 8918) };
error: no note found for object a7a7324ea645b881658fb78d2e7e049f48970afd.
210367ec889(v1_1_8):eval.c
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 6674) struct METHOD {
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 6675) VALUE klass, oklass;
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 6676) VALUE recv;
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 6677) ID id, oid;
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 6678) NODE *body;
210367ec889 (Yukihiro "Matz" Matsumoto 1999-01-20 04:59:39 +0000 6679) };
error: no note found for object 210367ec889f5910e270d6ea2c7ddb8a8d939e61.
ruby-trunk-changes の関連するページを正規のリンクに直して箇条書きした。
- https://ruby-trunk-changes.hatenablog.com/entry/ruby_trunk_changes_20220930
- https://ruby-trunk-changes.hatenablog.com/entry/20180131/ruby_trunk_changes_62111_62123
- https://ruby-trunk-changes.hatenablog.com/entry/20171006/ruby_trunk_changes_60123_60129
- https://ruby-trunk-changes.hatenablog.com/entry/20160819/ruby_trunk_changes_55962_55970
- https://ruby-trunk-changes.hatenablog.com/entry/20150816/ruby_trunk_changes_51591_51593
- https://ruby-trunk-changes.hatenablog.com/entry/20150707/ruby_trunk_changes_51158_51174
- https://ruby-trunk-changes.hatenablog.com/entry/20150705/ruby_trunk_changes_51142_51150
- https://ruby-trunk-changes.hatenablog.com/entry/20150703/ruby_trunk_changes_51111_51127
- https://ruby-trunk-changes.hatenablog.com/entry/20151002/ruby_trunk_changes_51996_52005
- https://ruby-trunk-changes.hatenablog.com/entry/20150606/ruby_trunk_changes_50786_50792
- https://ruby-trunk-changes.hatenablog.com/entry/20150605/ruby_trunk_changes_50768_50785
- https://ruby-trunk-changes.hatenablog.com/entry/20150603/ruby_trunk_changes_50737_50751
- https://ruby-trunk-changes.hatenablog.com/entry/20150602/ruby_trunk_changes_50718_50736
- https://ruby-trunk-changes.hatenablog.com/entry/20120806/ruby_trunk_changes_36629_36647
- https://ruby-trunk-changes.hatenablog.com/entry/20120803/ruby_trunk_changes_36601_36612
- https://ruby-trunk-changes.hatenablog.com/entry/20120802/ruby_trunk_changes_36589_36600
- https://ruby-trunk-changes.hatenablog.com/entry/20110726/ruby_trunk_changes_32666_32672