a = Object.new.instance_eval{ @x = 42 and self }
p a.dup
a.instance_eval{ class << self; include Singleton; end }
p a.dup
harp:~ > ruby a.rb
#<Object:0xb75cbb44 @x=42>
/home/ahoward//lib/ruby/1.8/singleton.rb:71:in `dup': can't dup instance of singleton Object (TypeError)
from a.rb:7
this is a side effect of strong dynamic type systems: the interpreter/compiler
cannot know until runtime if a methods signature makes sense becaues there are
an infinite variety of ways the semantics of a msg sent to an object might
change betweent two transmissions to the same object. if you don't like this
there are two choices:
- use language with a strong static type system. this rules out python,
java, c++, c, perl, lisp, and smalltalk
- dispair
regards.
-a
···
On Sun, 18 Feb 2007, Stefan Rusterholz wrote:
Care to explain why you chose defining a method with the sole purpose of
raising an exception over removing the method instead?
--
we can deny everything, except that we have the possibility of being better.
simply reflect on that.
- the dalai lama
you should check out haskell - it's one of only a few languages that can
provide this feature.
-a
···
On Sun, 18 Feb 2007, Stefan Rusterholz wrote:
My issue is that I can't test that. I can only try and catch the exception.
With dup that's not too terrible as it doesn't have side-effects. Still in
my oppinion having to run code to see what happens is not a clean behaviour.
--
we can deny everything, except that we have the possibility of being better.
simply reflect on that.
- the dalai lama
because we serve it sometimes. in addition, most of our employees know how to
make it at any time. we might not have it today though. our we might, but
we're out of meatballs.
-a
···
On Sun, 18 Feb 2007, Stefan Rusterholz wrote:
I'll try to explain it differently, depict my issue. Say you go to a
restaurant, take a look at the card and see "Spagetthi". You order Spagetthi
but the waiter just tells you "Oh, we don't serve Spagetthi here.". You'd
naturally ask "Why put it on the card then if you don't serve it at all?"
--
we can deny everything, except that we have the possibility of being better.
simply reflect on that.
- the dalai lama
You could conceivably have a case where an object can't be dup'd, but is
mutable, like a singleton class. If dup returns self, then you could end up
changing the object when you didn't want to. It's probably not an everyday
problem... but I still don't like the idea of having to remember that "dup"
means "dup or self".
IF the proposed implementation were to do what you suggested - rescue
every dup error by returning self - then I would agree that it's a bad
design feature to put into the language.
I personally believe that returning self for symbols, fixnums, true,
false, and nil is not bad or dangerous in any way. Can you provide a
single example (even if contrived) where this could produce an
unintended result? I can only come up with one myself, and it's too
contrived for me to consider it a danger.
···
On Feb 16, 3:28 pm, "Gregory Brown" <gregory.t.br...@gmail.com> wrote:
On 2/16/07, Robert Dober <robert.do...@gmail.com> wrote:
> On 2/16/07, Phrogz <g...@refinery.com> wrote:
> > b) You should never ever write "a.dup rescue a" because it will give
> > you strange problems if a might refer to a mutable object that doesn't
> > respond to #dup.
> Neve say never but when you write
> a.dup rescue a
> you should be aware of that potential danger
Right. My only point was that this solved what the OP asked for
without being hard.
It just seems like that solution is no better or worse than changing
the behaviour of dup, except for the fact that it puts the burden of
bad design into the programmer's hands, and not that of the
programming language
>I'll try to explain it differently, depict my issue. Say you go to a
>restaurant, take a look at the card and see "Spagetthi". You order
>Spagetthi but the waiter just tells you "Oh, we don't serve Spagetthi
>here.". You'd naturally ask "Why put it on the card then if you don't
>serve it at all?"
I imagine the waiter telling you "Oh, we don't serve Spaghetti
_today_".
matz.
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
Care to explain why you chose defining a method with the sole purpose of
raising an exception over removing the method instead?
yes - for illustration
And in a real situation, why would you chose to do so? What would be the
reasoning to justify that?
this is a side effect of strong dynamic type systems
I am well aware of that. I used ruby for over a year
But you in this situations you have two options, define a method whichs
only code is "raise Exception" or not define the method at all.
Or in your example the choice is between redefining the method with one
whichs only code is "raise Exception" or undefine the existing one.
In both situations: why would you chose one over the other?
I'm sorry if I'm obnoxious with that
> My issue is that I can't test that. I can only try and catch the
> exception. With dup that's not too terrible as it doesn't have
> side-effects. Still in my oppinion having to run code to see what
> happens is not a clean behaviour.
Oh, good point.
>> 1.respond_to?(:dup)
=> true
Then you need to rescue the exception.
If you *really* need this behaviour, you could just stick it in a file
somewhere and require it.
>> class Fixnum
>> undef :dup
>> end
=> nil
>> 2.dup
NoMethodError: undefined method `dup' for 2:Fixnum
Oh no, you don't wanna do that: What if you're a library and a user
assumes :dup is defined? What if you use a library that assumes it and
don't know about it?
···
On 2/17/07, Gregory Brown <gregory.t.brown@gmail.com> wrote:
On 2/17/07, Stefan Rusterholz <apeiros@gmx.net> wrote:
BTW, Matz, the only difference I suppose is that by having a
NoMethodError, we could make use of respond_to? as a check, but I
don't know if I think it's such a big deal that I'd be in support of a
RCR.
OO Languages are Class oriented languages
Dynamic Languages are Object oriented languages.
Replace Class with Type and you see what I mean.
This is all very much IMHO of course but I feel that the Ruby
community has made me evolve a lot away from "Class oriented".
Interesting points, especially about the implications of
"class-centric" vs. "object-centric" programming.
It's true that I rarely ever run into LSP issues, even in Java code. I
think it reflects, in part, the general movement OOD towards
de-emphasizing inheritance in favor of composition through
abstractions, etc. I would rather have the richness of Object and
Kernel, even with some LSP issues.
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.
>
> > > b) You should never ever write "a.dup rescue a" because it will give
> > > you strange problems if a might refer to a mutable object that doesn't
> > > respond to #dup.
> > Neve say never but when you write
> > a.dup rescue a
> > you should be aware of that potential danger
>
> Right. My only point was that this solved what the OP asked for
> without being hard.
> It just seems like that solution is no better or worse than changing
> the behaviour of dup, except for the fact that it puts the burden of
> bad design into the programmer's hands, and not that of the
> programming language
IF the proposed implementation were to do what you suggested - rescue
every dup error by returning self - then I would agree that it's a bad
design feature to put into the language.
I personally believe that returning self for symbols, fixnums, true,
false, and nil is not bad or dangerous in any way. Can you provide a
single example (even if contrived) where this could produce an
unintended result? I can only come up with one myself, and it's too
contrived for me to consider it a danger.
the only things I can think of involve singleton methods
def nil.foo
"hi there"
end
=> nil
nil.foo
=> "hi there"
b = nil.dup
TypeError: can't dup NilClass
from (irb):13:in `dup'
from (irb):13
def b.bar; "confusing?"; end
Imagine no error was thrown by that dup.
bar would be defined both on the duped (really not duped at all) nil
in your b variable, and on nil itself.
This of course is contrived, but it would be surprising behaviour. (I think)
···
On 2/16/07, Phrogz <gavin@refinery.com> wrote:
On Feb 16, 3:28 pm, "Gregory Brown" <gregory.t.br...@gmail.com> wrote:
> On 2/16/07, Robert Dober <robert.do...@gmail.com> wrote:
> > On 2/16/07, Phrogz <g...@refinery.com> wrote:
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
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".
harp:~ > cat a.rb
module DupSelf
def dup() self end
end
nil.extend DupSelf
p nil.dup
harp:~ > ruby a.rb
nil
regards.
-a
···
On Sun, 18 Feb 2007, Stefan Rusterholz wrote:
Yukihiro Matsumoto wrote:
>I'll try to explain it differently, depict my issue. Say you go to a
>restaurant, take a look at the card and see "Spagetthi". You order
>Spagetthi but the waiter just tells you "Oh, we don't serve Spagetthi
>here.". You'd naturally ask "Why put it on the card then if you don't
>serve it at all?"
I imagine the waiter telling you "Oh, we don't serve Spaghetti
_today_".
matz.
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
--
we can deny everything, except that we have the possibility of being better.
simply reflect on that.
- the dalai lama
I've already made it clear I don't think it's a good idea in the
general sense, I'm just saying that if the behaviour change is
necessary or important to you, it's easy to add.
Whether or not it's good practice is an entirely seperate question.
I would be tempted to bludgeon library writers who find it convenient
to undef core methods, to be honest.
For client code that doesn't have to play nice with others? Have at
it! (You *are* writing tests that make sure your code is working
right, aren't you? )
···
On 2/17/07, SonOfLilit <sonoflilit@gmail.com> wrote:
Oh no, you don't wanna do that: What if you're a library and a user
assumes :dup is defined? What if you use a library that assumes it and
don't know about it?
Care to explain why you chose defining a method with the sole purpose of
raising an exception over removing the method instead?
yes - for illustration
And in a real situation, why would you chose to do so? What would be the
reasoning to justify that?
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'.
another is
module DRbUndumped
def _dump(dummy) # :nodoc:
raise TypeError, 'can\'t dump'
end
end
this is more useful than it looks. what it means is that any object in a
hierarchy will cause a particular exception to get thrown, indicating that a
drb proxy should be used. this is a good approach because you can mark objects
which are normally able to be marshaled as not being so in a way that's viral
to other objects holding references to this object.
this is a side effect of strong dynamic type systems
I am well aware of that. I used ruby for over a year
sorry for being pendantic then.
But you in this situations you have two options, define a method whichs
only code is "raise Exception" or not define the method at all.
Or in your example the choice is between redefining the method with one
whichs only code is "raise Exception" or undefine the existing one.
In both situations: why would you chose one over the other?
I'm sorry if I'm obnoxious with that
that's ok.
cheers.
-a
···
On Sun, 18 Feb 2007, Stefan Rusterholz wrote:
On Sun, 18 Feb 2007, Stefan Rusterholz wrote:
--
we can deny everything, except that we have the possibility of being better.
simply reflect on that.
- the dalai lama
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.
regards.
-a
···
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.
--
we can deny everything, except that we have the possibility of being better.
simply reflect on that.
- the dalai lama
> ...
>
> OO Languages are Class oriented languages
> Dynamic Languages are Object oriented languages.
> Replace Class with Type and you see what I mean.
>
> This is all very much IMHO of course but I feel that the Ruby
> community has made me evolve a lot away from "Class oriented".
Interesting points, especially about the implications of
"class-centric" vs. "object-centric" programming.
It's true that I rarely ever run into LSP issues, even in Java code. I
think it reflects, in part, the general movement OOD towards
de-emphasizing inheritance in favor of composition through
abstractions, etc. I would rather have the richness of Object and
Kernel, even with some LSP issues.
Interesting - and comforting - to know.
I do not have the luxury to follow more than Ruby nowadays (and I try
to find time for Smalltalk very hard, in vein so far).
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?
> ...
Cheers
Robert
···
On 2/17/07, Dean Wampler <deanwampler@gmail.com> wrote:
--
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
A very good case. Enough so that I change my vote from "change dup" to
"leave things as they are".
···
On Feb 16, 4:47 pm, "Gregory Brown" <gregory.t.br...@gmail.com> wrote:
On 2/16/07, Phrogz <g...@refinery.com> wrote:
> I personally believe that returning self for symbols, fixnums, true,
> false, and nil is not bad or dangerous in any way. Can you provide a
> single example (even if contrived) where this could produce an
> unintended result? I can only come up with one myself, and it's too
> contrived for me to consider it a danger.
the only things I can think of involve singleton methods
>> def nil.foo
>> "hi there"
>> end
=> nil
>> nil.foo
=> "hi there"
>> b = nil.dup
TypeError: can't dup NilClass
from (irb):13:in `dup'
from (irb):13
>> def b.bar; "confusing?"; end
Imagine no error was thrown by that dup.
bar would be defined both on the duped (really not duped at all) nil
in your b variable, and on nil itself.
This of course is contrived, but it would be surprising behaviour. (I think)
But they never do seem to run out of chunky bacon.
···
On 2/17/07, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:
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".