Overriding to_s

B

Brad

All:

This is probably going to seem a bit silly, however I will ask
anyway. :)

Is there a way to override the to_s method such that it takes a
parameter? For example, if I wanted to provide a format specifier
for a number:

class Numeric
def to_s(optFormat)
if !optFormat.nil?
# format a string based on the optFormat format
# specifier.
retVal = format_number(self,optFormat)
else
retVal = self.to_s
end
retVal
end
end

payment=600 # $6.00
puts(payment.to_s('$#.##'))

(* not a perfect specimen of a ruby script, but it gets the
idea across *)

Any help with this matter, is greatly appreciated. :)

Regards,
Brad
 
T

ts

B> Is there a way to override the to_s method such that it takes a
B> parameter? For example, if I wanted to provide a format specifier
B> for a number:

well, you have several problems

B> class Numeric

#to_s is defined in Integer, Float, Bignum, ... not in Numeric

If you define it in Numeric, ruby will use the old definition in
Integer, ...

B> def to_s(optFormat)

you are saying that #to_s must have a parameter, this mean that you can't
call it 12.to_s

Perhaps best to write it

def to_s(optFormat = nil)

now Integer#to_s can take an optional argument, this mean that your new
method #to_s is not really adapted for Integer (except if format_number
take this in count)

B> if !optFormat.nil?
B> # format a string based on the optFormat format
B> # specifier.
B> retVal = format_number(self,optFormat)
B> else
B> retVal = self.to_s

here, you call recursively #to_s.

Perhaps best to alias #to_s before redefining it, and call the alias

B> end
B> retVal
B> end
B> end


Guy Decoux
 
B

Brad

ts said:
B> Is there a way to override the to_s method such that it takes a
B> parameter? For example, if I wanted to provide a format specifier
B> for a number:

well, you have several problems

B> class Numeric

#to_s is defined in Integer, Float, Bignum, ... not in Numeric

If you define it in Numeric, ruby will use the old definition in
Integer, ...

B> def to_s(optFormat)

you are saying that #to_s must have a parameter, this mean that you can't
call it 12.to_s

Perhaps best to write it

def to_s(optFormat = nil)

now Integer#to_s can take an optional argument, this mean that your new
method #to_s is not really adapted for Integer (except if format_number
take this in count)

B> if !optFormat.nil?
B> # format a string based on the optFormat format
B> # specifier.
B> retVal = format_number(self,optFormat)
B> else
B> retVal = self.to_s

here, you call recursively #to_s.

Perhaps best to alias #to_s before redefining it, and call the alias

B> end
B> retVal
B> end
B> end


Guy Decoux

Guy:

Thanks for the speedy response!

I guess I was being a bit naive, I thought Numeric was a base class
for Integer, Float, etc. Is there any way to redefine to_s across
the board, i.e. for Integer, Float, etc without having to duplicate
code for each numeric type?

Yeah, the code is pretty shabby :,. I didn't put much thought into it
as it was only meant to be an illustration. Don't get me wrong though
you're points are very good and obviously are not part of my native
ruby thinking, otherwise the sample would have included them. Thank
you. :)


Hopefully I don't sound rude. :/

Regards,
Brad
 
T

ts

B> I guess I was being a bit naive, I thought Numeric was a base class
B> for Integer, Float, etc. Is there any way to redefine to_s across

Well, I've seen that I've said a stupidity : this is Fixnum which redefine
#to_s and not Integer

Numeric is a base class for Fixnum and Float

svg% ruby -e 'p Fixnum.ancestors; p Float.ancestors'
[Fixnum, Integer, Precision, Numeric, Comparable, Object, Kernel]
[Float, Precision, Numeric, Comparable, Object, Kernel]
svg%

but these 2 classes re-define #to_s

svg% ruby -e 'p Fixnum.instance_methods(false).grep(/to_s$/)'
["to_s"]
svg%

svg% ruby -e 'p Float.instance_methods(false).grep(/to_s$/)'
["to_s"]
svg%

svg% ruby -e 'p Integer.instance_methods(false).grep(/to_s/)'
[]
svg%

svg% ruby -e 'p Numeric.instance_methods(false).grep(/to_s/)'
[]
svg%

B> the board, i.e. for Integer, Float, etc without having to duplicate
B> code for each numeric type?

wait for 2.0. I suspect that some persons will use wrapper to do this
(probably not its right use, I don't know ...)


Guy Decoux
 
B

Brad

ts said:
B> I guess I was being a bit naive, I thought Numeric was a base class
B> for Integer, Float, etc. Is there any way to redefine to_s across

Well, I've seen that I've said a stupidity : this is Fixnum which redefine
#to_s and not Integer

Numeric is a base class for Fixnum and Float

svg% ruby -e 'p Fixnum.ancestors; p Float.ancestors'
[Fixnum, Integer, Precision, Numeric, Comparable, Object, Kernel]
[Float, Precision, Numeric, Comparable, Object, Kernel]
svg%

but these 2 classes re-define #to_s

svg% ruby -e 'p Fixnum.instance_methods(false).grep(/to_s$/)'
["to_s"]
svg%

svg% ruby -e 'p Float.instance_methods(false).grep(/to_s$/)'
["to_s"]
svg%

svg% ruby -e 'p Integer.instance_methods(false).grep(/to_s/)'
[]
svg%

svg% ruby -e 'p Numeric.instance_methods(false).grep(/to_s/)'
[]
svg%

B> the board, i.e. for Integer, Float, etc without having to duplicate
B> code for each numeric type?

wait for 2.0. I suspect that some persons will use wrapper to do this
(probably not its right use, I don't know ...)


Guy Decoux
Guy:

Thanks again for the reply, I defined my own to_s for Fixnum and Float
(aliasing original to_s) and this seems to be working for me.

This should hold me over until Ruby 2.0 is released. :)

Thanks,
Brad
 

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,772
Messages
2,569,591
Members
45,103
Latest member
VinaykumarnNevatia
Top