Re: [問題] 關於stdlib matrix
: 推 godfat:為什麼你覺得需要修改 Fixnum..? 12/12 22
: → rexkimta:要用1*Matrix[[1,2],[3,4]]這種型式的語法,不是就應該 12/12 22
: → rexkimta:定義Fixnum*Matrix嗎?不然至少也要修改Numeric? 12/12 22
ok, 因為我沒用過 matrix, 所以不知道這樣可以動。這種時候就是
Use the source, Tux 的時候了。首先我們先翻到 Fixnum#*
https://github.com/ruby/ruby/blob/900b4a6db63012d9ce32a1019a7c9d5b014a0047/
numeric.c#L3609
rb_define_method(rb_cFixnum, "*", fix_mul, 1);
所以我們去找 fix_mul 這個 c function:
https://github.com/ruby/ruby/blob/900b4a6db63012d9ce32a1019a7c9d5b014a0047/
numeric.c#L2575-2582
這邊可以看到 fix_mul 在 rhs 不是 FIXNUM_P(y) 時,會去 FIXNUM_P(y)
由於什麼都不是,最後會跑到 return rb_num_coerce_bin(x, y, '*');
接下來就看 rb_num_coerce_bin 是什麼:
https://github.com/ruby/ruby/blob/900b4a6db63012d9ce32a1019a7c9d5b014a0047/
numeric.c#L219-224
我們會看到重點是 do_coerce(&x, &y, TRUE); 接著就去看他的定義:
https://github.com/ruby/ruby/blob/900b4a6db63012d9ce32a1019a7c9d5b014a0047/
numeric.c#L198-217
在 L206 的地方,可以看到 ruby 又呼叫 coerce_body, 取得某個 array,
並把 lhs 和 rhs 分別替換成這個 coerce_body 回傳的 array 的 first 和 last.
接著看 coerce_body 定義:
https://github.com/ruby/ruby/blob/900b4a6db63012d9ce32a1019a7c9d5b014a0047/
numeric.c#L179-183
這裡我們看到,coerce_body 會對 rhs 呼叫 id_coerce, 再查一下 id_coerce
https://github.com/ruby/ruby/blob/900b4a6db63012d9ce32a1019a7c9d5b014a0047/
numeric.c#L3540
可以發現其實就是 :coerce, 一個 ruby 的 symbol. 也就是說,他嘗試呼叫
rhs.coerce lhs
套到這裡來,其實就是 Matrix[[1,2],[3,4]].coerce 1
並把其結果重新定為 lhs 和 rhs, 再套 * 上去。
測試一下:
Matrix[[1,2],[3,4]].coerce 1
會得到:
[#<Matrix::Scalar:0x000001009991d8 @value=1>, Matrix[[1, 2], [3, 4]]]
也就是說,當我們寫:
1 * Matrix[[1,2],[3,4]]
時,ruby 會先看 matrix 不是 numeric, 因此呼叫 Matrix#coerce 1
把 1 改寫成 scalar, 並當作新的 lhs, 再把原本的 matrix 當作 rhs.
在 matrix.rb 中,就可以找到這個 Matrix#coerce 的定義:
def coerce(other)
case other
when Numeric
return Scalar.new(other), self
else
raise TypeError, "#{self.class} can't be coerced into #{other.class}"
end
end
因此我們可以定義一個 Two class:
class Two
def coerce lhs
[lhs, 2]
end
end
然後得到 100 * Two.new # => 200
--
By Gamers, For Gamers - from the past Interplay
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.135.38.235
推
12/13 11:22, , 1F
12/13 11:22, 1F
討論串 (同標題文章)
完整討論串 (本文為第 2 之 2 篇):
Ruby 近期熱門文章
PTT數位生活區 即時熱門文章