Prev: Thread error "undefined method `keys' for nil:NilClass"
Next: Getting version from PE executables
From: RichardOnRails on 29 Oct 2009 21:18 Hi, In The Well Grounded Rubyist (which, along with The Ruby Way, I love), Dave Black presents a justification for the x++ omission in Ruby. I thought I'd see whether I could implement just the incrementing portion of C's x++ functionality (without the prefix/ postfix issues) in pure Ruby. I wasnt willing to delve into Matz implementation of higher-level Ruby functions or low-level C/C++ code. Below is what I came up with. Q1. Test 1 failed, I imagine, because the interpret thought Ah, 7s a Fixnum which I ve seen billions of times, so I know what to do with it. Thus, it ignored my over-riding definition of Fixnum. So I call it compiler error, to use the vernacular, by reporting that x had no method pp. Am I all wet? Test 2 passed, but it with a couple of anomalies: Q2. x.to_s yielded xs class and address, suggesting x had become a semi-Fixed Num, i.e, x now stored a REFERENCE to the to xs data, rather than the immediate storage of the data, as interpreter is wont to do with Fixnums. Am I all wet? Q3. y.inspect yielded only its value (8) and nothing else, suggesting the x.pp yielded a full-fledged Fixnum. Am I all wet? Dave Black argues that since Fixnum values use immediate storage rather than referenced storage, x=1;x++ would be akin to changing 1 into 2. This example somewhat supports that view, but the interpreter sidestepped the matter by creating a reference for xs value and an immediate value for y (=x.pp). Any ideas, Richard class FixNum attr :val def initialize (fixnum) puts "Initializing object %d" % fixnum raise "Initializer not a Fixnum" if fixnum.class != Fixnum puts "\nInitializing Fixnum to %d" % fixnum @val = fixnum end def pp @val+=1 end end # Test 1 (Failure) x = 7; y = x.pp; z =x.class # undefined method `pp' for 7:Fixnum (NoMethodError) # Test 2 (Success) x = FixNum.new(7); y = x.pp; z =x.class puts [x.to_s, y.inspect, z.to_s].join("; ") # => <FixNum:0x2b62694>; 8; FixNum
From: RichardOnRails on 30 Oct 2009 09:42 On Oct 29, 9:18 pm, RichardOnRails <RichardDummyMailbox58...(a)USComputerGurus.com> wrote: > Hi, > > In The Well Grounded Rubyist (which, along with The Ruby Way, I > love), Dave Black presents a justification for the x++ omission in > Ruby. I thought I'd see whether I could implement just the > incrementing portion of C's x++ functionality (without the prefix/ > postfix issues) in pure Ruby. I wasnt willing to delve into Matz > implementation of higher-level Ruby functions or low-level C/C++ > code. Below is what I came up with. > > Q1. Test 1 failed, I imagine, because the interpret thought Ah, 7s > a Fixnum which I ve seen billions of times, so I know what to do with > it. Thus, it ignored my over-riding definition of Fixnum. So I > call it compiler error, to use the vernacular, by reporting that x > had no method pp. Am I all wet? > > Test 2 passed, but it with a couple of anomalies: > > Q2. x.to_s yielded xs class and address, suggesting x had become a > semi-Fixed Num, i.e, x now stored a REFERENCE to the to xs data, > rather than the immediate storage of the data, as interpreter is wont > to do with Fixnums. Am I all wet? > > Q3. y.inspect yielded only its value (8) and nothing else, > suggesting the x.pp yielded a full-fledged Fixnum. Am I all wet? > > Dave Black argues that since Fixnum values use immediate storage > rather than referenced storage, x=1;x++ would be akin to changing 1 > into 2. This example somewhat supports that view, but the > interpreter sidestepped the matter by creating a reference for xs > value and an immediate value for y (=x.pp). > > Any ideas, > Richard > > class FixNum > attr :val > def initialize (fixnum) > puts "Initializing object %d" % fixnum > raise "Initializer not a Fixnum" if > fixnum.class != Fixnum > puts "\nInitializing Fixnum to %d" % fixnum > @val = fixnum > end > > def pp > @val+=1 > end > end > > # Test 1 (Failure) > x = 7; y = x.pp; z =x.class # undefined method `pp' for 7:Fixnum > (NoMethodError) > > # Test 2 (Success) > x = FixNum.new(7); y = x.pp; z =x.class > puts [x.to_s, y.inspect, z.to_s].join("; ") # => <FixNum:0x2b62694>; > 8; FixNum Hi, Please ignore my questions. I just discovered a major mistake: I thought I was overriding Ruby's Fixnum class, but I misspelled it at FixNum. That error invalidates most if not all of the things I reported. Mea Culpa. I'll correct my errors and probably have a new theory subsequently. Best wishes, Richard
From: Robert Klemme on 30 Oct 2009 11:05 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"). Which brings us to the question: what is the advantage of immutable numbers? First, it avoids errors that could be caused by aliasing (two objects refer the same object, one of them changes it, it changes for the other one as well without being expected). Then, it is quite natural if you consider mathematical numbers: they cannot change. Additionally, the expression "1" can always refer to the same object (in reality it's a bit different but from a Ruby programmer's perspective the difference is not noticeable) which in fact makes using numeric constants very efficient (as opposed to the expression "'foo'" which constructs a new String instance on every invocation, albeit with a shared char array underneath which eases the pain a bit). This in turn makes integer math pretty efficient because if numbers were mutable Ruby would have to create a new object for every result of an operator evaluation. I am not saying that Ruby is ideal for number crunching but it could be significantly slower if certain design decisions would have been made differently. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
From: lith on 30 Oct 2009 13:51 > 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. You could "decorate" it with such a method though. This could look something like this: class FixNum < BasicObject def initialize(fn) @fn = fn end def succ! @fn += 1 end def method_missing(*args, &block) @fn.send(*args, &block) end end a = FixNum.new(1) a.succ! p a => 2 Whether this is good practice or marginally useful ...
From: Rajinder Yadav on 30 Oct 2009 14:41
On Fri, Oct 30, 2009 at 1:51 PM, lith <minilith(a)gmail.com> wrote: >> 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. > > You could "decorate" it with such a method though. This could look > something like this: > > class FixNum < BasicObject > > def initialize(fn) > @fn = fn > end > > def succ! > @fn += 1 > end > > def method_missing(*args, &block) > @fn.send(*args, &block) > end Hi lith, can you extol your knowledge on me about what method_missing is doing? I get what *args and &block is, but not quite sure what's going on? > end > > a = FixNum.new(1) > a.succ! > p a > => 2 > > Whether this is good practice or marginally useful ... > > -- Kind Regards, Rajinder Yadav http://DevMentor.org Do Good! - Share Freely, Enrich and Empower people to Transform their lives |