Assign inside a class method

V

Voltaire

Hi, great language
Exactly I want to implement a postfix increment, but I don't know how to
assign inside the class method

class Numeric
def postAdd(val)
old = self
self += val ????
old
end
end



Thanks
 
P

Phil Tomson

Hi, great language
Exactly I want to implement a postfix increment, but I don't know how to
assign inside the class method

class Numeric
def postAdd(val)
old = self
self += val ????
old
end
end

This isn't going to work for Numeric.

Just like you can't do:

9+= 1

(you can't assign 10 to 9 )


But you can do:

a = 9
a+= 1

because then you change the value that 'a' references.

Phil
 
V

Voltaire

I put that 'self += val ????' meaning 'how to substitute that'.
I would have at least tried that before posting ? !
you completely missed my question (or my question is weird? or too
simple for the experts?)
I do not teach people what they don't ask for.
Thanks anyway
 
P

Phil Tomson

I put that 'self += val ????' meaning 'how to substitute that'.
I would have at least tried that before posting ? !
you completely missed my question (or my question is weird? or too
simple for the experts?)
I do not teach people what they don't ask for.
Thanks anyway

Sorry. I did think you tried it before you posted and found it didn't
work. My answer was basically that you can't do what you're asking
because it involves reassigning self. And since Numeric's are immediate
values you can't change them because it would involve reassigning to self.

I don't think it's too simple a question or too weird: I've had it myself.

If I'm still missing the question, please restate it so I (or someone
else here) can take another shot at it.

Phil
 
D

daz

Voltaire said:
I put that 'self += val ????' meaning 'how to substitute that'.
I would have at least tried that before posting ? !
you completely missed my question (or my question is weird? or too
simple for the experts?)
I do not teach people what they don't ask for.
Thanks anyway


Phil's answer was good for what he thought
you were trying to do.

In your postAdd method, self is the value
referred to by the variable.
You have no access to the variable itself.


class Numeric
def post_add(val)
self + val
end
end

n = 6 ; val = 4
p [ n.post_add(val), n] # n is unchanged

n = 6 ; val = 4
p [n = n.post_add(val), n] # assign back to n

n = 6 ; val = 4
p [n += val , n] # without using post_add

#-> [10, 6]
#-> [10, 10]
#-> [10, 10]


# Or, if you want to redefine +=,
# just redefine +
# += should then work as you expect

class Fixnum
alias oplus +
def +(val)
puts "self is #{self}"
oplus(val).oplus(100)
end
end

n = 6 ; val = 4
p [n += val, n]

#-> self is 6
#-> [110, 110]


If your question isn't answered yet, give an example
of what you expect in x and n after:

n = 6
x = n.post_add(4)


daz
 
C

Christoph

:
....
Sorry. I did think you tried it before you posted and found it didn't
work. My answer was basically that you can't do what you're asking
because it involves reassigning self. And since Numeric's are immediate
values you can't change them because it would involve reassigning to self.

I think the term ``immediate value'' is used when talking about instances of
the Fixnum, Symbol, FalseClass, TrueClass or NilClass - it is basically an
implementation issue.

Anyway the argument used, that you cannot possibly implement a ``postAdd''
method (btw. you want an instances NOT a class method) in a true to the
spirit object-oriented language like Ruby, is the statelessness of numbers.
Meaning, that
sending 3 the message of adding 4 to itself (and returning the
previous state)
doesn't makes a whole lot of sense, since this the new state, 7,
is not an altered state of ``3'', but really a whole new object
(the number 7).

You can make the same argument for Arrays, Hashes or Strings however this
would make Ruby prohibitively inefficient. In this context it is interesting
to
note, that Python sports stateless strings and that Python's method
arguments
are a special kind of stateless Arrays (Tuples).
Also note that Ruby's ``stateless numbers'' really hinders Ruby's
algorithmic
efficiency when dealing with huge Bignums...
I don't think it's too simple a question or too weird: I've had it myself.

Ditto ...


Just for the heck of it - Here is a Numeric Wrapper class whose
instances probably behave more in tune with your preconceptions ...


----
class Numeric
def rep
self
end
end

class Wrapper
include Comparable
attr_reader :rep
alias inspect rep
alias to_s rep

def initialize(num)
@rep = num.rep
end

op_mths =[:%,:&,:*,:**,:+,:+@,:-,:-@,:/,:abs,:remainder] # etc.
# Note to simplify things we explicitly left out examples
# of methods with negative arity.

op_mths.each {|mth|
arity = 42.method(mth).arity
mth = mth.to_s
sgn = Array.new(arity){|i| "_#{i}" }.join(',')
args = Array.new(arity){|i| "_#{i}.rep" }.join(',')
body = "def #{mth}(#{sgn}) Wrapper.new(@rep.#{mth}(#{args})) end"
class_eval body
}

bool_mths =[:zero?,:<,:<=,:<=>,:between? ] # etc.
bool_mths.each {|mth|
arity = 42.method(mth).arity
mth = mth.to_s
sgn = Array.new(arity){|i| "_#{i}" }.join(',')
args = Array.new(arity){|i| "_#{i}.rep" }.join(',')
body = "def #{mth}(#{sgn}) @rep.#{mth}(#{args}) end"
class_eval body
}

def coerce(other)
[other,rep]
end

def post_add(rhs)
tmp = clone
@rep = @rep + rhs.rep
tmp
end
end


p a = Wrapper.new(3) # 3
p 6.0 / a # 2.0
p a.post_add(4) # 3
p a # 7
p a < 3 # false
 
V

Voltaire

Thanks to Phil & daz

I used to program in C++. Now playing with ruby (for now).
What I wanted was just that: method that increments the value of the
class instance
but returns the old value. Don't no why, i was thinking that the Numeric
and its subclasses were already implemented as wrappers.
Pitty they are not!!! There's no performance penalty imho implementing
that. To me it seemed unbeleivable that it cannot be done.
I really was thinking that my knowledge of ruby didn't allow me to do that.

Was playing with column widths
e.g.
w = [3, 4, 7, 6]
wanting to generate offsets for using with split etc.
offset = 0
w.map { |x| (offset += x) - x }
this too: [0] + w[0..-2].map { |x| offset += x }

i would like it: w.map { |x| offset.postAdd(x) }

I will do it with wrappers if i ever really need that.

Thanks again :)
I put that 'self += val ????' meaning 'how to substitute that'.
I would have at least tried that before posting ? !
you completely missed my question (or my question is weird? or too
simple for the experts?)
I do not teach people what they don't ask for.
Thanks anyway



Phil's answer was good for what he thought
you were trying to do.

In your postAdd method, self is the value
referred to by the variable.
You have no access to the variable itself.


class Numeric
def post_add(val)
self + val
end
end

n = 6 ; val = 4
p [ n.post_add(val), n] # n is unchanged

n = 6 ; val = 4
p [n = n.post_add(val), n] # assign back to n

n = 6 ; val = 4
p [n += val , n] # without using post_add

#-> [10, 6]
#-> [10, 10]
#-> [10, 10]


# Or, if you want to redefine +=,
# just redefine +
# += should then work as you expect

class Fixnum
alias oplus +
def +(val)
puts "self is #{self}"
oplus(val).oplus(100)
end
end

n = 6 ; val = 4
p [n += val, n]

#-> self is 6
#-> [110, 110]


If your question isn't answered yet, give an example
of what you expect in x and n after:

n = 6
x = n.post_add(4)


daz
 
V

Voltaire

Wonderfull, that's what I needed
Beginner in ruby, going to study that :)
An idea/question:
Is it possible to localize the instance at run-time ?
def post_add (val)
o = self
me = find_me // meaning find the variable / instance
// that is calling this method
me += val
o
end
Thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top