[#23657] [Bug #1550] String#lstrip! raises RuntimeError on Frozen String Despite Making No Changes — Run Paint Run Run <redmine@...>

Bug #1550: String#lstrip! raises RuntimeError on Frozen String Despite Making No Changes

13 messages 2009/06/01

[#23729] [Bug #1583] Time + String no Longer Raises TypeError? — Run Paint Run Run <redmine@...>

Bug #1583: Time + String no Longer Raises TypeError?

14 messages 2009/06/05

[#23770] [Bug #1595] rake unusable on windows install — Robert Gonzalez <redmine@...>

Bug #1595: rake unusable on windows install

10 messages 2009/06/09

[#23869] [Bug #1640] [PATCH] Documentation for the Rational Class — Run Paint Run Run <redmine@...>

Bug #1640: [PATCH] Documentation for the Rational Class

12 messages 2009/06/16

[#23903] [Bug #1648] Rational#div Raises NoMethodError for Invalid Argument — Run Paint Run Run <redmine@...>

Bug #1648: Rational#div Raises NoMethodError for Invalid Argument

9 messages 2009/06/17

[#23977] [ANN] meeting log of RubyDeveloperKaigi20090622 — "Yugui (Yuki Sonoda)" <yugui@...>

Hi,

41 messages 2009/06/23
[#23979] Re: [ANN] meeting log of RubyDeveloperKaigi20090622 — Run Paint Run Run <runrun@...> 2009/06/23

Thanks for the update. :-)

[#24173] Re: [ANN] meeting log of RubyDeveloperKaigi20090622 — "NARUSE, Yui" <naruse@...> 2009/07/07

Sorry for late response,

[#24174] Re: [ANN] meeting log of RubyDeveloperKaigi20090622 — Luis Lavena <luislavena@...> 2009/07/07

On Tue, Jul 7, 2009 at 12:12 AM, NARUSE, Yui<naruse@airemix.jp> wrote:

[#24242] Re: [ANN] meeting log of RubyDeveloperKaigi20090622 — Charles Oliver Nutter <headius@...> 2009/07/09

On Mon, Jul 6, 2009 at 10:18 PM, Luis Lavena<luislavena@gmail.com> wrote:

[#24010] [Bug #1685] Some windows unicode path issues remain — B Kelly <redmine@...>

Bug #1685: Some windows unicode path issues remain

26 messages 2009/06/24
[#29189] [Bug #1685] Some windows unicode path issues remain — Yuki Sonoda <redmine@...> 2010/04/01

Issue #1685 has been updated by Yuki Sonoda.

[#29200] Re: [Bug #1685] Some windows unicode path issues remain — Bill Kelly <billk@...> 2010/04/01

Yuki Sonoda wrote:

[#29892] Re: [Bug #1685] Some windows unicode path issues remain — Bill Kelly <billk@...> 2010/04/29

Hi,

[#24058] [Bug #1696] http downloads are unuseably slow — Steven Hartland <redmine@...>

Bug #1696: http downloads are unuseably slow

19 messages 2009/06/27

[#24063] [Feature #1697] Object#<=> — Marc-Andre Lafortune <redmine@...>

Feature #1697: Object#<=>

15 messages 2009/06/28

[ruby-core:23758] Re: Ducktyping interface

From: brian ford <brixen@...>
Date: 2009-06-08 20:33:02 UTC
List: ruby-core #23758
Hi,

On Sat, Jun 6, 2009 at 5:19 PM, Yehuda Katz <wycats@gmail.com> wrote:
> Matz,
> I've been working on adding some specs to RubySpec related to the ducktyping
> interface. I have observed the following behavior and want to know whether
> or not it's intentional. Let's use the #to_s coercion as an example:
> 1. If the object has a method #to_s, it's called.
> 2. If #to_s returns something that is not a String, a TypeError is raised.
> In MRI, the mechanism for determining if an object has a method #to_s is to
> call respond_to?. This means that even if the method does not exist, #to_s
> will get called, and fall through to #method_missing, if the #respond_to
> method returns true for :to_s. As a result, when using MRI, it is possible
> to implement the duck-typing interface without defining #to_s, but instead
> defining a combination of #respond_to? and #method_missing that returns a
> String.

Here are some example specs that illustrate the two ideas. Currently,
the RubySpecs are silent about whether #respond_to? *must* be called.
The basic specs are like these:

describe "Kernel#String()" do
  it "calls #to_s to convert an arbitrary object to a String" do
    obj = mock('test')
    obj.should_receive(:to_s).and_return("test")

    String(obj).should == "test"
  end

  it "raises a TypeError if #to_s does not exist" do
    obj = mock('to_s')
    obj.undefine(:to_s)

    lambda { String(obj) }.should raise_error(TypeError)
  end

  it "raises a TypeError if #to_s does not return a String" do
    (obj = mock('123')).should_receive(:to_s).and_return(123)
    lambda { String(obj) }.should raise_error(TypeError)
  end

  it "returns the same object if it is already a String" do
    string = "Hello"
    string.should_not_receive(:to_s)
    string2 = String(string)
    string.should equal(string2)
  end

  it "returns the same object if it is an instance of a String subclass" do
    subklass = Class.new(String)
    string = subklass.new("Hello")
    string.should_not_receive(:to_s)
    string2 = String(string)
    string.should equal(string2)
  end
end

If #respond_to? must be called, these specs are added to the ones above:

describe "Kernel#String()" do
  # ...

  it "raises a TypeError if respond_to? returns false for #to_s" do
    obj = mock("to_s")
    obj.does_not_respond_to(:to_s)

    lambda { String(obj) }.should raise_error(TypeError)
  end

  it "raises a NoMethodError if #to_s is not defined but
#respond_to?(:to_s) returns true" do
    obj = Object.new
    obj.undefine(:to_s)
    obj.responds_to(:to_s)

    lambda { String(obj) }.should raise_error(NoMethodError)
  end

  it "calls #to_s if #respond_to?(:to_s) returns true" do
    obj = mock('to_s')
    obj.undefine(:to_s)
    obj.fake!(:to_s, "test")

    String(obj).should == "test"
  end
end

Also, whatever is the decision about this, can we please clarify
whether it applies only to String(), Float(), Integer(), or whether it
applies to any place that #to_s, #to_i, #to_int, etc. are called in
MRI. Another way to phrase this is: If MRI calls
rb_funcall(some_method) inside of method #foo, should calling
#some_method be considered part of the public interface of method
#foo.

Thanks,
Brian

> Is this intentional? Would it be ok for an alternative implementation to
> look up the #to_s method using an internal check instead of calling the
> user-defined #respond_to?, as MRI does?
> In other words, is the only "correct" way to enlist in Ruby coercion to
> define to_s explicitly, or is another correct way to define respond_to? and
> method_missing to return an appropriate response?
> --
> Yehuda Katz
> Developer | Engine Yard
> (ph) 718.877.1325
>

In This Thread