[Ruby] string.to_primitive and string.to_collection
Michael Judge
mjudge at surveycomplete.com
Tue Oct 3 17:49:25 PDT 2006
I don't contribute to the mailing list often, but today I was working on
a DSL and came up with an interesting pair of snippets for working with
user data.
-----
Snippet 1: Convert a string to its most appropriate primitive type
(i.e., string, integer or float.)
Examples:
"12".to_primitive #=> 12
"13.8".to_primitive #=> 13.8
"abc".to_primitive #=> "abc"
Code:
class String
def to_primitive
begin
return Integer(self)
rescue
# Try next.
end
begin
return Float(self)
rescue
# Try next.
end
return self
end
end
-----
Snippet 2. Convert a multi-line string into its most appropriate
collection type (i.e., array or hash.) For hashes, each line should
fit the format: key. value or key: value. (The key should be one word.)
How is this useful? Well, you can fake a here-doc constructor for
hashes and arrays.
Examples:
# Hashes
%{
1. Angie
2. David
3. Google
4. Elliott
5. Michelle
6. Stephen
7. Cort
}.to_collection
=> {5=>"Michelle", 6=>"Stephen", 1=>"Angie", 7=>"Cort", 2=>"David",
3=>"Google", 4=>"Elliott"}
# Arrays
%{
Angie
David
Google
Elliott
Michelle
Stephen
Cort
}.to_collection
=> ["Angie", "David", "Google", "Elliott", "Michelle", "Stephen",
"Cort"]
# Real-world example:
question "s2a" {
label "What was the research you participated in about? (MARK ALL
THAT APPLY.)"
multiple %{
1. Automobiles
2. Arts and crafts products
3. Office products
4. Computers
5. Food or beverages
6. None of these
}
}
# method 'multiple' prefers a hash or array parameter. It uses
.to_collection to convert incoming strings.
Snippet Code:
class String
def to_collection
hash_types = {}
array_types = []
self.each_line do |line|
case line.strip!
when /^([^\s\:\.]+)\s*[\:\.]\s*(.*?)$/
hash_types[$1.to_primitive] = $2.to_primitive
when ""
# Ignore blank lines
else
array_types << line.to_primitive
end
end
throw "hash and list styles intermixed" unless
hash_types.empty? or array_types.empty?
return '' if hash_types.empty? and array_types.empty?
return hash_types unless hash_types.empty?
return array_types unless array_types.empty?
end
end
-----
I'm always interested in easier ways to construct arrays and hashes
inline. If anyone has an alternate, I'd love to hear it. It was only
recently that I discovered %{} for multi-line strings.
(By the way, I did look into YAML. The character escaping frightened
me a little.)
-----
Michael Judge
More information about the Ruby
mailing list