Oppinions on RCR for dup on immutable classes

Yukihiro Matsumoto wrote:

Hi,

>Um, no, with the classes mentioned in the RCR the answer would be
>"never", not just "today". You'd have to buy the Restaurant and exchange
>to cook to change the answer :slight_smile:

If we see a class as a restaurant, your illustration makes sense. But
from my point of view, we don't know the name of the restaurant, nor
its menu. We just sit and cry for "Spaghetti!", and sometimes the
waiter says "I'm sorry".

              matz.

The example translates to:
Restaurant := Class
Menucard := #methods
Say "we don't serve that" := raised Exception

If it changes from time to time I agree with you. But if it is "never",
the restaurant shouldn't put the menu on the card in the first time - in
my oppinion :slight_smile:

My regards

···

In message "Re: Oppinions on RCR for dup on immutable classes" > on Sun, 18 Feb 2007 01:37:19 +0900, Stefan Rusterholz > <apeiros@gmx.net> writes:

--
Posted via http://www.ruby-forum.com/\.

unknown wrote:

the one that springs to mind is

   module Mixin
     def average
       total.to_f / n.to_f
     end
     def total
       raise NotImplementedError
     end
     def n
       raise NotImplementedError
     end
   end

this give a much nicer error than NameError or something about nil not
responding to 'to_f'.

module Mixin
  def average
    total().quo(n())
  end
end

a) uses Rational if possible ;-p (ok, besides the point)
b) no superfluous code
c) no additional exception

I'm sorry, I still fail to see the point in defining a method that says
the method can't be executed (put a menu that isn't actually served on
the menucard - put it on the menucard when it is served)

My regards

···

--
Posted via http://www.ruby-forum.com/\.

... or even if it doesn't: method_missing

-a

···

On Sun, 18 Feb 2007 Ara.T.Howard@noaa.gov wrote:

On Sun, 18 Feb 2007, Dean Wampler wrote:

As someone else commented, perhaps the real issue is that
5.respond_to?(:dup) returns true yet 5.dup raises, so you have no way of
knowing in advance that you shouldn't call dup.

i simply do not understand this line of thinking - every call to every object
always has that characteristic

f.respond_to? :read #=> true
f.gets # EOFError

q.respond_to? :pop #=> true
q.pop(true) #=> ThreadError if empty

to me this really seems like a dynamic vs static issue - i just don't see how
ruby can save you, regardless of the impl of dup, or any other method. one
cannot avoid hanlding runtime exceptions in a dynamic language. one cannot
know in advance whether it's ok to call something - even if the object
responds to it.

--
we can deny everything, except that we have the possibility of being better.
simply reflect on that.
- the dalai lama

one cannot
know in advance whether it's ok to call something - even if the object
responds to it.

With this in mind, what do you guys think of this work around?

[sandal@metta payroll_camping]$ irb
class Object
  def dup?
    dup
  rescue TypeError
    false
  end
end

=> nil

3.dup?

=> false

3.dup? || 3

=> 3

"foo".dup?

=> "foo"

···

On 2/17/07, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

Hi --

As someone else commented, perhaps the real issue is that
5.respond_to?(:dup) returns true yet 5.dup raises, so you have no way
of knowing in advance that you shouldn't call dup.

That just came up recently and I agree that this is kind of inelegant
(euphemistically)
Maybe that would be a reasonable CR?

See Ara's answer to Dean, though. respond_to? isn't designed to tell
you what will happen when you call the method. Lots of objects
respond to methods by raising exceptions.

Maybe the reason people don't like dup doing that is that it *always*
does it for some classes of object. But I think that's in order to
leave no mysteries. dup is "advertised", so to speak, as something
that every object can do. So when an object can't do it, it's more
gracious to explain why not (in the exception message).

It's a lot like this:

   irb(main):001:0> (0..10).to_a
   => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
   irb(main):002:0> (0.0..10.0).to_a
   TypeError: can't iterate from Float

Ranges with floats in them could just undef to_a and not respond, but
the expectation exists that all ranges have some meaningful
relationship to the process of being converted into an array
(including the relationship of opting out of it but in a way that
tells you what's going on).

I realize that two ranges are of the same class while, say, a string
and nil aren't. But it's not a class thing; it's more about
collective (not necessary along class lines) behaviors and
expectations.

David

···

On Sun, 18 Feb 2007, Robert Dober wrote:

On 2/17/07, Dean Wampler <deanwampler@gmail.com> wrote:

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

Hi --

···

On Sun, 18 Feb 2007, Stefan Rusterholz wrote:

Yukihiro Matsumoto wrote:

Hi,

In message "Re: Oppinions on RCR for dup on immutable classes" >> on Sun, 18 Feb 2007 01:37:19 +0900, Stefan Rusterholz >> <apeiros@gmx.net> writes:

>Um, no, with the classes mentioned in the RCR the answer would be
>"never", not just "today". You'd have to buy the Restaurant and exchange
>to cook to change the answer :slight_smile:

If we see a class as a restaurant, your illustration makes sense. But
from my point of view, we don't know the name of the restaurant, nor
its menu. We just sit and cry for "Spaghetti!", and sometimes the
waiter says "I'm sorry".

              matz.

The example translates to:
Restaurant := Class
Menucard := #methods
Say "we don't serve that" := raised Exception

But methods are not constrained by class. It's not the class's
responsibility to oversee the object's methods. I'm not sure where
the object fits into your model.

David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

the difference is in the rescue.

rescue NoMethodError

is not the same thing as

rescue NotImplementedError

···

On 2/17/07, Stefan Rusterholz <apeiros@gmx.net> wrote:

unknown wrote:
> the one that springs to mind is
>
> module Mixin
> def average
> total.to_f / n.to_f
> end
> def total
> raise NotImplementedError
> end
> def n
> raise NotImplementedError
> end
> end
>
> this give a much nicer error than NameError or something about nil not
> responding to 'to_f'.

module Mixin
  def average
    total().quo(n())
  end
end

a) uses Rational if possible ;-p (ok, besides the point)
b) no superfluous code
c) no additional exception

I'm sorry, I still fail to see the point in defining a method that says
the method can't be executed (put a menu that isn't actually served on
the menucard - put it on the menucard when it is served)

same semantics - but nice and clean.

-a

···

On Sun, 18 Feb 2007, Gregory Brown wrote:

On 2/17/07, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

one cannot
know in advance whether it's ok to call something - even if the object
responds to it.

With this in mind, what do you guys think of this work around?

[sandal@metta payroll_camping]$ irb
class Object
  def dup?
    dup
  rescue TypeError
    false
  end
end

=> nil

3.dup?

=> false

3.dup? || 3

=> 3

"foo".dup?

=> "foo"

--
we can deny everything, except that we have the possibility of being better.
simply reflect on that.
- the dalai lama

Hi --

one cannot
know in advance whether it's ok to call something - even if the object
responds to it.

With this in mind, what do you guys think of this work around?

[sandal@metta payroll_camping]$ irb
class Object
  def dup?
    dup
  rescue TypeError
    false
  end
end

=> nil

3.dup?

=> false

3.dup? || 3

=> 3

"foo".dup?

=> "foo"

false.dup? # => false :slight_smile:

I'm not sure what I think of it. I'm trying to think of how it would
be used, given that it's a ?-method that returns something other than
true/false. Would you do this, for example:

   if (d = x.dup?)

I'm not sure that reads very well; it really kind of conceals the fact
that d might be an actual dup of x (at least to my eyes). But I'm
probably not thinking of all the places it might be used.

David

···

On Sun, 18 Feb 2007, Gregory Brown wrote:

On 2/17/07, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

Hi --

>>
>> As someone else commented, perhaps the real issue is that
>> 5.respond_to?(:dup) returns true yet 5.dup raises, so you have no way
>> of knowing in advance that you shouldn't call dup.
> That just came up recently and I agree that this is kind of inelegant
> (euphemistically)
> Maybe that would be a reasonable CR?

See Ara's answer to Dean, though. respond_to? isn't designed to tell
you what will happen when you call the method. Lots of objects
respond to methods by raising exceptions.

Maybe the reason people don't like dup doing that is that it *always*
does it for some classes of object. But I think that's in order to
leave no mysteries. dup is "advertised", so to speak, as something
that every object can do. So when an object can't do it, it's more
gracious to explain why not (in the exception message).

It's a lot like this:

   irb(main):001:0> (0..10).to_a
   => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
   irb(main):002:0> (0.0..10.0).to_a
   TypeError: can't iterate from Float

Ranges with floats in them could just undef to_a and not respond, but
the expectation exists that all ranges have some meaningful
relationship to the process of being converted into an array
(including the relationship of opting out of it but in a way that
tells you what's going on).

I realize that two ranges are of the same class while, say, a string
and nil aren't. But it's not a class thing; it's more about
collective (not necessary along class lines) behaviors and
expectations.

Very well put David. I can only agree, it is better behavior.
Sorry Ara if I missed that post of yours this thread is a little bit complex.
R.

···

On 2/17/07, dblack@wobblini.net <dblack@wobblini.net> wrote:

On Sun, 18 Feb 2007, Robert Dober wrote:
> On 2/17/07, Dean Wampler <deanwampler@gmail.com> wrote:

David

--
Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    (See what readers are saying! http://www.rubypal.com/r4rrevs.pdf\)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

--
We have not succeeded in answering all of our questions.
In fact, in some ways, we are more confused than ever.
But we feel we are confused on a higher level and about more important things.
-Anonymous

Hi,

If we see a class as a restaurant, your illustration makes sense. But
from my point of view, we don't know the name of the restaurant, nor
its menu. We just sit and cry for "Spaghetti!", and sometimes the
waiter says "I'm sorry".

The example translates to:
Restaurant := Class
Menucard := #methods
Say "we don't serve that" := raised Exception

I don't deny your model, but it smells like static typing. In Ruby,
we do

  obj.dup

not,

  void foo(SomeClass obj) {
    obj.dup();
  }

We don't see any class in Ruby example, we just see an object, and
order it to dup, assuming it can dup itself, without knowing whether
it is really able to dup. If it can't, for some reason, it raises an
exception. The best illustration for the situation (in Ruby, not
being Java) is something like above "sit and order" model.

              matz.

···

In message "Re: Oppinions on RCR for dup on immutable classes" on Sun, 18 Feb 2007 02:54:42 +0900, Stefan Rusterholz <apeiros@gmx.net> writes:

Gregory Brown wrote:

the difference is in the rescue.

rescue NoMethodError

is not the same thing as

rescue NotImplementedError

That's getting off-topic. The error dup gives is "not possible", not
"not implemented". Different story.
If you check previous messages you might figure that I can understand
the use in abstract classes (or mixins here) even though I'd do it
differently.

My regards.

···

--
Posted via http://www.ruby-forum.com/\.

+1

···

ara.t.howard@noaa.gov wrote:

With this in mind, what do you guys think of this work around?

[sandal@metta payroll_camping]$ irb
class Object
  def dup?
    dup
  rescue TypeError
    false
  end
end

=> nil

3.dup?

=> false

3.dup? || 3

=> 3

"foo".dup?

=> "foo"

same semantics - but nice and clean.

--
Vincent Fourmond, PhD student (not for long anymore)
http://vincent.fourmond.neuf.fr/

I'm not sure that reads very well; it really kind of conceals the fact
that d might be an actual dup of x (at least to my eyes). But I'm
probably not thinking of all the places it might be used.

Let me just play devils advocate for a sec.

4.nonzero?

=> 4

0.nonzero?

=> nil

I just think that dup? is a good compromise for third party hacking.
Not an RCR.

That having been said, I've not used nonzero? and I too am expecting
booleans from things that end in ?, but that was the best thing I
could come up with :wink:

···

On 2/17/07, dblack@wobblini.net <dblack@wobblini.net> wrote:

Gregory Brown wrote:
> the difference is in the rescue.
>
> rescue NoMethodError
>
> is not the same thing as
>
> rescue NotImplementedError

That's getting off-topic. The error dup gives is "not possible", not
"not implemented". Different story.
If you check previous messages you might figure that I can understand
the use in abstract classes (or mixins here) even though I'd do it
differently.

Actually, My point was about expressiveness through exceptions.
That is what you seem to be missing

3.dup

TypeError: can't dup Fixnum
        from (irb):1:in `dup'
        from (irb):1

TypeError is different than NoMethodError. In this case, it is
expressive of what is actually going wrong. Again, the difference is
in the rescue.

···

On 2/17/07, Stefan Rusterholz <apeiros@gmx.net> wrote: