Ruby-dev summary 19457-19539

Hello all,

This is a weekly summary of ruby-dev mailing list.

[ruby-dev:19457] equality between “a” and Exception.new(“a”)

Akira Tanaka asked if it is intended that ‘==’ doesn’t have commutativity.
This behavior comes from the equality checking mechanism of String.
For example, the following two expressions doesn’t return same value.

(a) “a” == Exception.new(“a”)
(b) Exception.new(“a”) == “a”

(a) returns true and (b) returns false. It is because Exception.new(“a”)
is automatically transformed to a String object “a” via to_str method in
case of (a). Matz changed a method for checking equality of strings as
follows.

In case of a == b and b is not a String object, the expression is true
if b has a method to_str and b == a is true.

[ruby-dev:19480] [RCR] Kernel#same?

Nobu Nakada requested a new method “same?”, that tests equality of
two objects in terms not only of the objects themselves but also of
instance variables they have. He also posted a patch to implement it.
Matz commented that we might develop a proper deep traverse framework
to support Marshal, deep-copy and this equality test, rather than
work around the recursive situation in traverse such like the Nobu’s
approach in the patch.

[ruby-dev:19494] [Oniguruma] Version 1.7
[ruby-dev:19514] [Oniguruma] Version 1.7.1

K.Kosako announced a new verion of Oniguruma library. You can get
it from:

ftp://ftp.ruby-lang.org/pub/ruby/contrib/onigd20030207.tar.gz
http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/oniguruma/

Here is the changelog in the announcement:

  1. improved speed (10% faster)
  2. added Cygwin support
  3. supported building DLL on Windows platform

There is a FreeBSD ports of Oniguruma by Akinori MUSHA:

http://www.FreeBSD.org/cgi/cvsweb.cgi/ports/devel/oniguruma/

Using ruby ports also available by him, FreeBSD users can easily
try building and testing it by setting WITH_ONIGURUMA=yes:

http://www.FreeBSD.org/cgi/cvsweb.cgi/ports/lang/ruby/ (1.6)
http://www.FreeBSD.org/cgi/cvsweb.cgi/ports/lang/ruby-devel/ (1.8)

[ruby-dev:19536] 1.8.0 preview2 (Re: Re: HAVE_* macros)

Matz considers about 1.8.0 and its release date. He wants to release
1.8.0 (not previews) soon and to concentrate on Rite development.
Also, he, and many Rubyists of course, expect a Test::Unit release
bundled with 1.8.0 officially.

Kazuo Saito ksaito@uranus.dti.ne.jp

Hi, I’m just a beginner buy program, but…

Quoteing ksaito@uranus.dti.ne.jp, on Mon, Feb 10, 2003 at 01:26:17AM +0900:

[ruby-dev:19457] equality between “a” and Exception.new(“a”)

Akira Tanaka asked if it is intended that ‘==’ doesn’t have commutativity.

I think anybody who has programmed with ruby for more than a few hours has
to know that

lhs == rhs

is the same as:

lhs.==(rhs)

or they won’t understand most things about the language.

So, == is obviously not commutative. Neither is any other method.

lhs.do_to rhs

If lhs doesn’t have a method “do_to”, but rhs does, ruby could reorder
this to

rhs.do_to lhs

but doesn’t.

This behavior comes from the equality checking mechanism of String.
For example, the following two expressions doesn’t return same value.

(a) “a” == Exception.new(“a”)
(b) Exception.new(“a”) == “a”

(a) returns true and (b) returns false. It is because Exception.new(“a”)
is automatically transformed to a String object “a” via to_str method in
case of (a). Matz changed a method for checking equality of strings as
follows.

In case of a == b and b is not a String object, the expression is true
if b has a method to_str and b == a is true.

If I understand this correctly, this is unpredictable and surprising to me.

For me, one test of sensibility would be the question: how do I get this
“commutative” behaviour for my own classes? Its easy to define a method
“+” that converts its arg to some type if necessary, but how do I get
ruby to reorder a “+” so that if my class is on the right, it gets
put on the left?

For example:

irb(main):018:0> “a” + 5
TypeError: failed to convert Fixnum into String
from (irb):18:in +' from (irb):18 irb(main):019:0> class Fixnum irb(main):020:1> def to_str irb(main):021:2> self.to_s irb(main):022:2> end irb(main):023:1> end nil irb(main):024:0> "a" + 5 "a5" irb(main):025:0> 5 + "a" TypeError: String can't be coerced into Fixnum from (irb):25:in +’
from (irb):25

Will this change apply to String.+, or just String.==?

Obviously, this is just my opinion.

Thanks for such a fun language,
Sam

In article 20030209190906.GA14768@debian,
Sam Roberts sroberts@uniserve.com writes:

Will this change apply to String.+, or just String.==?

Just String#==, Array#== and Hash#==.

I’m sure that matz don’t apply the change to + because + is not
commutative in general.

···


Tanaka Akira

Quoteing akr@m17n.org, on Mon, Feb 10, 2003 at 11:41:54AM +0900:

In article 20030209190906.GA14768@debian,
Sam Roberts sroberts@uniserve.com writes:

Will this change apply to String.+, or just String.==?

Just String#==, Array#== and Hash#==.

I’m sure that matz don’t apply the change to + because + is not
commutative in general.

I don’t understand, doesn’t

(a + b) == (b + a)

in general?

Actually, I think in general neither should be commutative, they aren’t
math, they are method calls.

Cheers,
Sam

In article 20030211044054.GA15912@debian,
Sam Roberts sroberts@uniserve.com writes:

I don’t understand, doesn’t

(a + b) == (b + a)

in general?

For example, “a” + “b” != “b” + “a”.

Actually, I think in general neither should be commutative, they aren’t
math, they are method calls.

method call is just a implementation.

Do you have any example for == which should not be commutative?

···


Tanaka Akira

Quoteing akr@m17n.org, on Tue, Feb 11, 2003 at 01:54:11PM +0900:

In article 20030211044054.GA15912@debian,
Sam Roberts sroberts@uniserve.com writes:

Actually, I think in general neither should be commutative, they aren’t
math, they are method calls.

method call is just a implementation.

It’s a fundamental property of the language. When you understand that
operators are method calls, you know how to program in Ruby.

Do you have any example for == which should not be commutative?

What I’m trying to say is this seems like a special purpose hack. It
doesn’t make == commutative: it makes == for 3 builtin classes
commutative.

The original example was

Exception == String

Well, what does this mean? I don’t know, what does Exception say it’s ==
operator does? An Exception is clearly NOT a string, so at some level
this doesn’t make sense, but I guess it defined something reasonable.
If not, I get Object.==, like in ALL OTHER CASES EXCEPT THREE BUILTIN
TYPES.

String == Exception

What does this mean? Well, String.== tries to coerce everything into a
string before comparing itself to it. I know what that means.

Anyhow, I won’t bother you guys any more with this.

Cheers,
Sam

Hi –

Do you have any example for == which should not be commutative?

Well, I would have thought this:

Exception.new(“a”) == “a”

:slight_smile: But seriously… my problem with that example being “true” is
that it’s only using Exception#to_s after doing a kind of
right-to-left backtracking, after seeing that a String object is –
no, was – needed. My instinct is to say: if you get as far as
having sent a message to an object, it’s too late to reconsider what
that object is.

Also, if == can backtrack, why not:

Exception.new(“a”) << “b” # #<Exception: ab>

and so on.

“Why not?” might be: having everything be exactly consistent and
symmetrical isn’t necessarily best for the language, and what’s good
for == isn’t automatically good for << and others. But I think having
any of this kind of right-to-left backtracking and re-evaluation feels
very anomalous.

David

···

On Tue, 11 Feb 2003, Tanaka Akira wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

In article 20030211150727.GC16278@debian,
Sam Roberts sroberts@uniserve.com writes:

method call is just a implementation.

It’s a fundamental property of the language. When you understand that
operators are method calls, you know how to program in Ruby.

Yes. So equality for == must be implemented by method call. Equality
assumes commutativity. Unfortunately commutativity is difficult to
implement because method call is not symmetrical as you said.
Especially it needs collaboration if left hand class has different
author to right hand class.

String is very difficult case because the author of String (matz)
cannot know == policy for other class written by an user. But
fortunately == should be commutative, matz can know the policy by
calling == method of the other class. Note that equality against
string is only meaningful for string like object, the == call is only
applied for classes which have to_str method which is the sign of “it
can be treated as a string in parameter”.

I know only one example which should be equal to String.

require ‘delegate’
d = SimpleDelegator.new(“abc”)
p d == “abc” #=> true
p “abc” == d #=> true

Since d delegates method calls to “abc”, it behaves as String even if
it is actually not a String. Note that to_str method of d is defined
as delegation because String has to_str.

What I’m trying to say is this seems like a special purpose hack. It
doesn’t make == commutative: it makes == for 3 builtin classes
commutative.

I think it shows “how to implement commutativity by method call”.
However it is somewhat restricted because Numeric has more powerful
system: coercion.

The original example was

Exception == String

Well, what does this mean? I don’t know, what does Exception say it’s ==
operator does? An Exception is clearly NOT a string, so at some level
this doesn’t make sense, but I guess it defined something reasonable.
If not, I get Object.==, like in ALL OTHER CASES EXCEPT THREE BUILTIN
TYPES.

It is true that “an Exception is clearly NOT a string”. So it returns
false.

String == Exception

What does this mean? Well, String.== tries to coerce everything into a
string before comparing itself to it. I know what that means.

No. String#== tried to coerce an object which have to_str method, not
everything. However we found the coercion was problematic because it
led non-commutative behavior.

By historical reason, Exception has to_str. Exception#to_str is used
as follows:

/pattern/ =~ exception

Such codes exist because $! was string in old days.

Anyway the equality between String and Exception is intended and
String#== and Exception#== implements it now. Do you have better way
to implement the equality?

Note that non-historical example of to_str is my pathname.rb. It
defines Pathname class which has to_str. So Pathname object can be
passed to various method which takes a string: File.open, etc.
Since it is not equal to string like exception, Pathname#== returns
false if an argument is a String. Thanks to current String#==,
String#== returns false if an argument is a Pathname.

···


Tanaka Akira

In article Pine.LNX.4.44.0302112122120.19718-100000@candle.superlink.net,
dblack@candle.superlink.net writes:

Well, I would have thought this:

Exception.new(“a”) == “a”

:slight_smile: But seriously… my problem with that example being “true” is
that it’s only using Exception#to_s after doing a kind of
right-to-left backtracking, after seeing that a String object is –
no, was – needed. My instinct is to say: if you get as far as
having sent a message to an object, it’s too late to reconsider what
that object is.

Since Exception.new(“a”) == “a” never returns true, your problem is
not exist.

···


Tanaka Akira

Hi –

···

On Wed, 12 Feb 2003, Tanaka Akira wrote:

In article Pine.LNX.4.44.0302112122120.19718-100000@candle.superlink.net,
dblack@candle.superlink.net writes:

Well, I would have thought this:

Exception.new(“a”) == “a”

:slight_smile: But seriously… my problem with that example being “true” is
that it’s only using Exception#to_s after doing a kind of
right-to-left backtracking, after seeing that a String object is –
no, was – needed. My instinct is to say: if you get as far as
having sent a message to an object, it’s too late to reconsider what
that object is.

Since Exception.new(“a”) == “a” never returns true, your problem is
not exist.

Whoops, I must have misunderstood the thread completely.

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav