From: RichardOnRails on
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 wasn’t 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, 7’s
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 x’s class and address, suggesting x had become a
“semi-Fixed Num”, i.e, x now stored a REFERENCE to the to x’s data,
rather than the immediate storage of the data, as interpreter is wont
to do with Fixnum’s. Am I all wet?

Q3. y.inspect yielded only it’s 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 x’s
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
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 wasn’t 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, 7’s
> 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 x’s class and address, suggesting x had become a
> “semi-Fixed Num”, i.e, x now stored a REFERENCE to the to x’s data,
> rather than the immediate storage of the data, as interpreter is wont
> to do with Fixnum’s.  Am I all wet?
>
> Q3. y.inspect yielded only it’s 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 x’s
> 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
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
> 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
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