[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Assign inside a class method

Peter

10/13/2003 12:50:00 AM

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

8 Answers

ptkwt

10/13/2003 6:44:00 AM

0

In article <6Fmib.32938$e6.1176616@twister2.libero.it>,
Voltaire <no_spam@no.where> wrote:
>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

Peter

10/13/2003 10:24:00 PM

0

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 Tomson wrote:
> In article <6Fmib.32938$e6.1176616@twister2.libero.it>,
> Voltaire <no_spam@no.where> wrote:
>
>>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

ptkwt

10/14/2003 3:34:00 AM

0

In article <TBFib.33460$vO5.1262606@twister1.libero.it>,
Voltaire <no_spam@no.where> wrote:
>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

>
>Phil Tomson wrote:
>> In article <6Fmib.32938$e6.1176616@twister2.libero.it>,
>> Voltaire <no_spam@no.where> wrote:
>>
>>>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
>


daz

10/14/2003 6:05:00 AM

0


"Voltaire" <no_spam@no.where> wrote:

> 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



Christoph

10/14/2003 7:35:00 AM

0

"Phil Tomson" wrote:
....
> 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
----


/Christoph


Peter

10/14/2003 4:26:00 PM

0

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 :)

daz wrote:
> "Voltaire" <no_spam@no.where> wrote:
>
>
>>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
>
>
>

Peter

10/14/2003 4:55:00 PM

0

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


Peter

10/14/2003 4:56:00 PM

0

Sorry, was addressed at Christoph

Voltaire wrote:
> 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
>
>