< :前の番号
^ :番号順リスト
> :次の番号
P :前の記事(スレッド移動)
N :次の記事(スレッド移動)
|<:前のスレッド
>|:次のスレッド
^ :返事先
_:自分への返事
>:同じ返事先を持つ記事(前)
<:同じ返事先を持つ記事(後)
---:分割してスレッド表示、再表示
| :分割して(縦)スレッド表示、再表示
~ :スレッドのフレーム消去
.:インデックス
..:インデックスのインデックス
Issue #7342 has been updated by jballanc (Joshua Ballanco).
File string_cmp.diff added
> The presence of #to_str indicates that the object obeys an entire String contract such that the C API can work with the object without making Ruby method calls.
Hmm... I was always under the impression that the distinction between #to_s and #to_str is that #to_s provides a (potentially lossy) string representation of any object, but #to_str will return a "string equivalent" of the object. As for the C API, the `rb_str_to_str` method does call #to_str if v#to_str exists and v is not already a string. I guess it would be good to get some clarification on this issue.
> You can use rb_check_funcall().
Thank you for the pointer, nobu! Actually, in looking at the implementation of String#<=> again I found some other oddities. For example, if Other#to_str is defined and Other#<=> returns a float, then `"a string" <=> Other.new` will return a float. I feel like this breaks the contract of #<=> as it should only ever return 1, 0, or -1. Anyhow, I've attached an updated patch that also includes some test fixes.
(Note: all tests in `make test-all` that passed before this patch pass after, however rubyspec will need to be updated. I will send a pull-request directly to the rubyspec project if this gets accepted.)
----------------------------------------
Bug #7342: String#<=> checks for a #to_str method on other but never uses it?
https://bugs.ruby-lang.org/issues/7342#change-33386
Author: jballanc (Joshua Ballanco)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: 2.0.0
=begin
This isn't exactly a bug, as much as a request for clarification. I was looking at the semantics of the (({<=>})) operator and noticed something curious. For most classes, when evaluating (({thing <=> other})), if (({other})) is not of a compatible type, then (({nil})) is returned.
The exceptions (as far as I can find) are String and Time. For the Time class, if (({other})) is not a kind of (({Time})), then the reverse comparison (({other <=> thing})) is tried and the inverse of this result is returned (if not nil). For String, the reverse comparison is only tried IF (({other.respond_to?(:to_str)})), HOWEVER the referenced (({other.to_str})) method is never called. For example:
class NotAString
def <=>(other)
1
end
def to_str
raise "I'm not a string!"
end
end
"test" <=> NotAString.new #=> -1
This seems very counterintuitive to me. I would expect that if my class implemented (({to_str})), that the return value of this would be used for comparison.
=end
--
http://bugs.ruby-lang.org/