Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Lexical Casts with Ruby

Reply
Thread Tools

Lexical Casts with Ruby

 
 
Rüdiger Sonderfeld
Guest
Posts: n/a
 
      09-03-2005
Hello,
I want to assign some values I recive in string form to attributes of a
user specified class. The problem is that I have to lexical cast the
strings into the required type. I can't use to_i or to_f because the attribute
type can only be determined at runtime.

Is there a way for lexical casts between types in Ruby? Something like
convert("10", Fixnum)
=> 10

Regards,
Rüdiger Sonderfeld <(E-Mail Removed)>
 
Reply With Quote
 
 
 
 
Robert Klemme
Guest
Posts: n/a
 
      09-03-2005
2005/9/3, R=FCdiger Sonderfeld <(E-Mail Removed)>:
> Hello,
> I want to assign some values I recive in string form to attributes of a
> user specified class. The problem is that I have to lexical cast the
> strings into the required type. I can't use to_i or to_f because the attr=

ibute
> type can only be determined at runtime.
>=20
> Is there a way for lexical casts between types in Ruby? Something like
> convert("10", Fixnum)
> =3D> 10


Well, there are several options:

You can use send, like your_string.send(:to_i) where you determine the
symbol (:to_i, :to_f etc) at runtime.

You can use case

result =3D case your_string
when /^\d+$/ then your_string.to_i
when /^\d.\.\d+/ then your_string.to_f
else your_string
end

Or you put conversions into a map

conv =3D {
Fixnum =3D> lambda {|x| x.to_i},
Float =3D> lambda {|x| x.to_f},
}

result =3D conv[Fixnum][your_string]

Hope, that gets you started.

Kind regards

robert


 
Reply With Quote
 
 
 
 
David A. Black
Guest
Posts: n/a
 
      09-03-2005
--8323328-1020658632-1125761734=:19128
Content-Type: MULTIPART/MIXED; BOUNDARY="8323328-1020658632-1125761734=:19128"

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

--8323328-1020658632-1125761734=:19128
Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE

Hi --

On Sun, 4 Sep 2005, [utf-8] R=C3=BCdiger Sonderfeld wrote:

> Hello,
> I want to assign some values I recive in string form to attributes of a
> user specified class. The problem is that I have to lexical cast the
> strings into the required type. I can't use to_i or to_f because the attr=

ibute
> type can only be determined at runtime.
>
> Is there a way for lexical casts between types in Ruby? Something like
> convert("10", Fixnum)
> =3D> 10


See Robert's answer. Also, another possibility would be to put the
knowledge directly in the object:

class MyClass
def x=3D(s)
@x =3D s.to_i
end

def y=3D(s)
@y =3D s.to_f
end

# ...
end

That way, you can just do:

obj.x =3D "10"

and have the conversion be encapsulated in the object.

If using the assignment syntax seems *too* transparent (since you're
not really setting it to "10"), you could use differently-named
methods. But the principle would be the same: put the knowledge in
the object.


David

--=20
David A. Black
http://www.velocityreviews.com/forums/(E-Mail Removed)
--8323328-1020658632-1125761734=:19128--
--8323328-1020658632-1125761734=:19128--


 
Reply With Quote
 
Paul Brannan
Guest
Posts: n/a
 
      09-07-2005
On Sun, Sep 04, 2005 at 12:16:26AM +0900, R??diger Sonderfeld wrote:
> Hello,
> I want to assign some values I recive in string form to attributes of a
> user specified class. The problem is that I have to lexical cast the
> strings into the required type. I can't use to_i or to_f because the attribute
> type can only be determined at runtime.
>
> Is there a way for lexical casts between types in Ruby? Something like
> convert("10", Fixnum)
> => 10


In C++, boost::lexical_cast uses streams to convert the object to a
string and then from the string to the desired type.

It is easy to do the first part in ruby; all objects have a to_s method.

The second part is harder. There is no uniform mechanism for converting
a string into an object.

Paul




 
Reply With Quote
 
Eric Mahurin
Guest
Posts: n/a
 
      09-07-2005
--- Paul Brannan <(E-Mail Removed)> wrote:

> On Sun, Sep 04, 2005 at 12:16:26AM +0900, R??diger Sonderfeld
> wrote:
> > Hello,
> > I want to assign some values I recive in string form to

> attributes of a
> > user specified class. The problem is that I have to lexical

> cast the
> > strings into the required type. I can't use to_i or to_f

> because the attribute
> > type can only be determined at runtime.
> >=20
> > Is there a way for lexical casts between types in Ruby?

> Something like
> > convert("10", Fixnum)
> > =3D> 10

>=20
> In C++, boost::lexical_cast uses streams to convert the
> object to a
> string and then from the string to the desired type.
>=20
> It is easy to do the first part in ruby; all objects have a
> to_s method.
>=20
> The second part is harder. There is no uniform mechanism for
> converting
> a string into an object.



A while back, I suggested adding some klass.from_* methods.=20
For example:

def Integer.from_s(s)
s.to_i;
end

Any class that could make one of its objects from a String
would put this method in. You could do the same for other
classes to convert from also: from_i, from_f, etc. Here would
be the usage:

Integer.from_s("10") # 10
10.to_s # "10" - nothing new

As a convienence you could also add this:

class String
def to(klass)
klass.from_s(self)
end
def self.from(obj)
obj.to_s
end
end

so you could do:

"10".to(Integer) # 10
String.from(10) # "10"

If this is a good solution for you, maybe an RCR for this more
general conversion mechanism is in order.



=09
=09
__________________________________________________ ____
Click here to donate to the Hurricane Katrina relief effort.
http://store.yahoo.com/redcross-donate3/


 
Reply With Quote
 
Paul Brannan
Guest
Posts: n/a
 
      09-08-2005
On Thu, Sep 08, 2005 at 02:09:32AM +0900, Eric Mahurin wrote:
> so you could do:
>
> "10".to(Integer) # 10
> String.from(10) # "10"
>
> If this is a good solution for you, maybe an RCR for this more
> general conversion mechanism is in order.


See RCR#280. The implementation is 34 lines long.

Paul




 
Reply With Quote
 
Eric Mahurin
Guest
Posts: n/a
 
      09-08-2005
--- Paul Brannan <(E-Mail Removed)> wrote:

> On Thu, Sep 08, 2005 at 02:09:32AM +0900, Eric Mahurin wrote:
> > so you could do:
> >=20
> > "10".to(Integer) # 10
> > String.from(10) # "10"
> >=20
> > If this is a good solution for you, maybe an RCR for this

> more
> > general conversion mechanism is in order.

>=20
> See RCR#280. The implementation is 34 lines long.


Don't know why I missed that one. I don't really like the
implementation with the global (or rather class variable) hash.
I would rather see an encapsulated API - each class gives
methods for converting to/from objects of other classes of
interest (i.e. String). You may have duplicated code or one
from_* calling another to_* (or vice-versa), but so what. This
way requires 0 lines of overhead - nothing needs to manage
framework. It's simple and is an extension of what we already
have. The klass#to(toKlass) and klass.from(fromObj) are
shortcuts to get a little more abstract if you want:

class String
def self.from(obj); obj.to_s; end
def to(klass); klass.from_s(self); end
end

If you did this, then I guess you could consider this the
overhead for each class that other classes want to convert
to/from - String, Integer, Float, Array, etc.

I would think this more straight-forward approach would be more
likely accepted.



=09
=09
__________________________________________________ ____
Click here to donate to the Hurricane Katrina relief effort.
http://store.yahoo.com/redcross-donate3/


 
Reply With Quote
 
gabriele renzi
Guest
Posts: n/a
 
      09-08-2005
Eric Mahurin ha scritto:
>>>If this is a good solution for you, maybe an RCR for this

>>
>>more
>>
>>>general conversion mechanism is in order.

>>
>>See RCR#280. The implementation is 34 lines long.

>
>
> Don't know why I missed that one. I don't really like the
> implementation with the global (or rather class variable) hash.
> I would rather see an encapsulated API - each class gives
> methods for converting to/from objects of other classes of
> interest (i.e. String).

<snip>

The reason for the global transformation table is basically being able
to handle any kind of "type" not just Classes. I like to think of ruby
as object based more than Class based.

Anyway, even if your approach is more conservative, I'd appreciate if it
was blessed[1].

I wonder what matz think of this stuff.


[1]
what I'd really like to see is multimethods. Just specialize #new and
everything goes fine
 
Reply With Quote
 
Paul Brannan
Guest
Posts: n/a
 
      09-08-2005
On Fri, Sep 09, 2005 at 03:49:59AM +0900, Eric Mahurin wrote:
> class String
> def self.from(obj); obj.to_s; end
> def to(klass); klass.from_s(self); end
> end
>
> If you did this, then I guess you could consider this the
> overhead for each class that other classes want to convert
> to/from - String, Integer, Float, Array, etc.
>
> I would think this more straight-forward approach would be more
> likely accepted.


Would you be more amenable to a solution like:

class Object
def to(type, *args, &block)
return send("to_#{type}", *args, &block)
end

def to_String
return to_s
end
end

class String
def to_Integer
return Integer(self)
end

# etc.
end

This eliminates the global constant by using double-dispatch, plus
retains the ability to convert to a non-class type (e.g.
foo.to(Enumerable)).

Paul




 
Reply With Quote
 
Eric Mahurin
Guest
Posts: n/a
 
      09-08-2005
--- Paul Brannan <(E-Mail Removed)> wrote:

> On Fri, Sep 09, 2005 at 03:49:59AM +0900, Eric Mahurin wrote:
> > class String
> > def self.from(obj); obj.to_s; end
> > def to(klass); klass.from_s(self); end
> > end
> >=20
> > If you did this, then I guess you could consider this the
> > overhead for each class that other classes want to convert
> > to/from - String, Integer, Float, Array, etc.
> >=20
> > I would think this more straight-forward approach would be

> more
> > likely accepted.

>=20
> Would you be more amenable to a solution like:
>=20
> class Object
> def to(type, *args, &block)
> return send("to_#{type}", *args, &block)
> end
>=20
> def to_String
> return to_s
> end
> end
>=20
> class String
> def to_Integer
> return Integer(self)
> end
>=20
> # etc.
> end
>=20
> This eliminates the global constant by using double-dispatch,
> plus
> retains the ability to convert to a non-class type (e.g.
> foo.to(Enumerable)).
>=20
> Paul


Let's say you have some aribitrary class that you want to
convert to/from a string. With the above, you'd put the
to-string method in this class and the from-string method in
String. I think better encapsulation would be to put both of
these in this new aribitrary class. To do it this way and
force the method names to have the class name in them, you'd do
this:

class Object
def self.from(obj,*args,&block)
send("from_#{self}".to_sym,obj,*args,&block)
rescue
obj.send("to_#{self}".to_sym,*args,&block)
end
def to(klass,*args,&block)
send("to_#{klass}".to_sym,*args,&block)
rescue
klass.send("from_#{self.class}".to_sym,self,*args, &block)
end
def to_String
to_s
end
def to_Integer
to_i
end
end


class Xyz
def self.from_String(s,base=3D10)
... make a Xyz from s ...
end
def to_String(base=3D10)
... make a String from self ...
end
end


Of course in the above, "klass" doesn't have to be a Class, but
it does need to respond to the right from_* method.

I'm not sure of the value of using from_String/to_String over
from_s/to_s. I think you'll have just a few classes that
you'll have many classes converting from/to them. You'll
never be able to convert from one arbitrary class to another.=20
Also, the above code is kind of ugly forming method names and
trying two different methods (not very duck-type like) - but I
could get over it.

Would this work with the non-class types you are talking about?




=09
=09
__________________________________________________ ____
Click here to donate to the Hurricane Katrina relief effort.
http://store.yahoo.com/redcross-donate3/


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem with TransformerHandler and Lexical events Collin VanDyck XML 0 11-30-2004 04:35 PM
Help with lexical events and a TransformerHandler Collin VanDyck Java 0 11-30-2004 03:05 PM
use streamtokenizer to implement lexical analyzer Eric Java 3 12-26-2003 08:28 PM
Python lexical scanner cricket Python 0 09-25-2003 03:58 PM
Lexical convention Ron C++ 0 08-30-2003 08:40 AM



Advertisments