Prev: Thread error "undefined method `keys' for nil:NilClass"
Next: Getting version from PE executables
From: Rick DeNatale on 30 Oct 2009 15:03 On Fri, Oct 30, 2009 at 11:05 AM, Robert Klemme <shortcutter(a)googlemail.com> wrote: > 2009/10/30 RichardOnRails <RichardDummyMailbox58407(a)uscomputergurus.com>: > >> I'll correct my errors and probably have a new theory subsequently. > > IMHO the story goes like this: absence of postfix ++ and -- is a > consequence of the fact that numeric types are immutable in Ruby which > makes an assignment necessary for these operators. Although that > would be doable, it would not immediately be obvious when looking at > "foo++". On the other side, "foo += 1" makes the assignment obvious > while still being pretty concise (you do not have to write "foo = foo > + 1"). I think that theres a more fundamental problem with ++ in a language like ruby, which has to do with the difference between objects and variables. The c ++ and -- operators change a variable, NOT a value. so in C a = 1 b = a a++ a is now 2, but b is still 1. Now, consider not immutable objects, but defining ++ for a mutable object. I've named the method plus_plus instead of ++ since I can do the former, but not the latter. class String def plus_plus self << " plus a plus" end end a = "A non-plussed string" b = a puts "a is #{a.inspect}" puts "b is #{b.inspect}" a.plus_plus puts "a is #{a.inspect}" puts "b is #{b.inspect}" When we run this we see that the result is: a is "A non-plussed string" b is "A non-plussed string" a is "A non-plussed string plus a plus" b is "A non-plussed string plus a plus" Because in languages like Ruby with object reference variable semantics, methods can only operate on objects, not the variables which reference them. So if you COULD successfully define Fixnum#++, or Fixnum#plus_plus: a = 1 a++ could only change the singleton instance of 1 into 2, which probably isn't something you'd really want to do. By 'you' I'm not aiming at you Robert. This reminds me of a very hard bug I encountered years ago when I was first was learning to program in Fortran. In the original Fortran you could assign a new value to a subroutine parameter inside the subroutine. If the actual parameter value was an integer literal, you could literally change 1 to 2, and that's why I know you probably don't want to do this. -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale
From: Marnen Laibow-Koser on 30 Oct 2009 16:32 Rajinder Yadav wrote: [...] > can you extol (Not what that word means.) > your knowledge on me about what method_missing is doing? http://www.ruby-doc.org/docs/ProgrammingRuby/html/ref_c_object.html#Object.method_missing Best, -- Marnen Laibow-Koser http://www.marnen.org marnen(a)marnen.org -- Posted via http://www.ruby-forum.com/.
From: Robert Klemme on 30 Oct 2009 18:19 On 10/30/2009 08:03 PM, Rick DeNatale wrote: > On Fri, Oct 30, 2009 at 11:05 AM, Robert Klemme > <shortcutter(a)googlemail.com> wrote: >> 2009/10/30 RichardOnRails <RichardDummyMailbox58407(a)uscomputergurus.com>: >> >>> I'll correct my errors and probably have a new theory subsequently. >> IMHO the story goes like this: absence of postfix ++ and -- is a >> consequence of the fact that numeric types are immutable in Ruby which >> makes an assignment necessary for these operators. Although that >> would be doable, it would not immediately be obvious when looking at >> "foo++". On the other side, "foo += 1" makes the assignment obvious >> while still being pretty concise (you do not have to write "foo = foo >> + 1"). > > I think that theres a more fundamental problem with ++ in a language > like ruby, which has to do with the difference between objects and > variables. > > The c ++ and -- operators change a variable, NOT a value. How their behavior is defined is completely up to the language designer. You could make "a++" syntactic sugar for (_tmp = a; a = a + 1; _tmp) in the same way as "a += 1" is syntactic sugar for "a = a + 1" or "a ||= 10" is syntactic sugar for "a || a = 10". In fact the sequence in brackets above would be a completely reasonable way to do it in Ruby: you could use "a++" in a similar way as in C++ and Java without sacrificing Fixnum's immutability. But: you would hide the assignment in the syntactic sugared version and this could lead to unexpected behavior, like a = 1 b = a a++ # now why is b still 1??? For someone unaware of the hidden assignment but aware of the fact that the object referenced by a must be mutable to make this work it would be surprising that b is not changed as well. You could only discover that by looking at #object_id of both (or using #equal?). > so in C > > a = 1 > b = a > a++ > > a is now 2, but b is still 1. Yes - and in C++ you can have it otherwise: robert(a)fussel:~$ g++ x.cc && ./a.out a++=1 a=2 b=2 robert(a)fussel:~$ cat x.cc #include <stdio.h> int main( int argc, const char* argv[] ) { int a = 1; int &b = a; printf("a++=%d\n", a++); printf("a=%d\n", a); printf("b=%d\n", b); return 0; } robert(a)fussel:~$ > Now, consider not immutable objects, but defining ++ for a mutable > object. I've named the method plus_plus instead of ++ since I can do > the former, but not the latter. > > class String > def plus_plus > self << " plus a plus" > end > end > > > a = "A non-plussed string" > b = a > > puts "a is #{a.inspect}" > puts "b is #{b.inspect}" > > a.plus_plus > > puts "a is #{a.inspect}" > puts "b is #{b.inspect}" > > When we run this we see that the result is: > > a is "A non-plussed string" > b is "A non-plussed string" > a is "A non-plussed string plus a plus" > b is "A non-plussed string plus a plus" > > Because in languages like Ruby with object reference variable > semantics, methods can only operate on objects, not the variables > which reference them. > > So if you COULD successfully define Fixnum#++, or Fixnum#plus_plus: > > a = 1 > a++ > > could only change the singleton instance of 1 into 2, which probably > isn't something you'd really want to do. Not necessarily. If this was implemented in the language the sequence "1" would be an object constructor in the same way as string "constants" are. robert(a)fussel:~$ ruby1.8 -e '2.times { puts "foo".object_id }' -605970738 -605970758 That would the only reasonable way to do it. Then there would be no singleton instance which in turn would have the said performance implications. I would consider the example from Fortran that you presented (changing the value of the constant 1) rather a bug either in the language implementation or in the design. This does not mean that other languages would have to repeat that. :-) Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
From: Simon Krahnke on 31 Oct 2009 13:16 * Robert Klemme <shortcutter(a)googlemail.com> (23:19) schrieb: > Yes - and in C++ you can have it otherwise: > > robert(a)fussel:~$ g++ x.cc && ./a.out > a++=1 > a=2 > b=2 > robert(a)fussel:~$ cat x.cc > > #include <stdio.h> > > int main( int argc, const char* argv[] ) > { > int a = 1; > int &b = a; > printf("a++=%d\n", a++); > printf("a=%d\n", a); > printf("b=%d\n", b); > return 0; > } No, you can't: $ ./ab a: 2 @ 0xbfe413f8 b: 2 @ 0xbfe413f8 $ cat ab.cc #include <iostream> int main(void) { int a = 1; int &b = a; a++; std::cout << "a: " << a << " @ " << &a << std::endl; std::cout << "b: " << b << " @ " << &b << std::endl; return 0; } There is only one variable, b is just another name for it. mfg, simon .... l
From: Christopher Dicely on 31 Oct 2009 14:02
On Fri, Oct 30, 2009 at 3:20 PM, Robert Klemme <shortcutter(a)googlemail.com> wrote: > On 10/30/2009 08:03 PM, Rick DeNatale wrote: >> >> On Fri, Oct 30, 2009 at 11:05 AM, Robert Klemme >> <shortcutter(a)googlemail.com> wrote: >>> >>> 2009/10/30 RichardOnRails <RichardDummyMailbox58407(a)uscomputergurus.com>: >>> >>>> I'll correct my errors and probably have a new theory subsequently. >>> >>> IMHO the story goes like this: absence of postfix ++ and -- is a >>> consequence of the fact that numeric types are immutable in Ruby which >>> makes an assignment necessary for these operators. Â Although that >>> would be doable, it would not immediately be obvious when looking at >>> "foo++". Â On the other side, "foo += 1" makes the assignment obvious >>> while still being pretty concise (you do not have to write "foo = foo >>> + 1"). >> >> I think that theres a more fundamental problem with ++ in a language >> like ruby, which has to do with the difference between objects and >> variables. >> >> The c ++ and -- operators change a variable, NOT a value. > > How their behavior is defined is completely up to the language designer. > Â You could make "a++" syntactic sugar for > > (_tmp = a; a = a + 1; _tmp) > > in the same way as "a += 1" is syntactic sugar for "a = a + 1" or "a ||= 10" > is syntactic sugar for "a || a = 10". Â In fact the sequence in brackets > above would be a completely reasonable way to do it in Ruby: you could use > "a++" in a similar way as in C++ and Java without sacrificing Fixnum's > immutability. I think it would make more sense, if you were going to define a "++" syntax for Ruby, to use "a.succ" rather than "a+1", and if you are going to create syntax which does an assignment but returns the pre-assignment value of the variable receiving the assignment, I'd go further and include a more general form for that, say ":=", such that "a := b" is equivalent to "(_ = a),(a = b), _" and then define postfix "++" such that "a++" is "a := a.succ" and prefix "++" such that "++a" is equivalent to "a = a.succ". |