Asp Forum
Home
|
Login
|
Register
|
Search
Forums
>
comp.lang.ruby
Defining a method to select values from a hash.
Danny Tatom
5/29/2009 12:30:00 AM
I'm terribly confused with this, and can't seem to figure it out (or
explain it).
Using HTTParty, I have a method that grabs some XML and returns it as a
hash:
def check(data)
@results = self.class.post('/checkDocument', :query => {:key =>
@key,
:data => data})
end
def errors
errors = @results['results']['error']
end
An example of the hash it returns:
>> atd.check("I'm realy hating this wether")
=> [{"suggestions"=>{"option"=>["really", "ready", "real", "relay",
"realty"]}, "precontext"=>"I'm", "type"=>"spelling", "string"=>"realy",
"description"=>"Spelling"}, {"suggestions"=>{"option"=>["weather",
"whether"]},
"url"=>"
http://service.afterthedeadline.com/info.slp?text=we...
,
"precontext"=>"this", "type"=>"spelling", "string"=>"wether",
"description"=>"Did you mean..."}]
Now calling the .errors method, I can get the string from each one like
this:
>> atd.errors.each { |error| p error['string'] }
"realy"
"wether"
What I'd like to do is write a method for string, so that
atd.errors.each { |error| p.error.string } would result in the same
thing. For the life of me, I can't figure out how to do that. :/
The other problem I'm having with the way I'm doing it now is that
calling .errors.each when there's only one error sent back gives me a
"can't convert String into Integer" error.
So, if anyone could point me in the right direction, I'd appreciate it.
:)
--
Posted via
http://www.ruby-...
.
1 Answer
Brian Candler
5/29/2009 8:36:00 AM
0
You want foo['bar'] and foo.bar to be the same thing, like in
Javascript? In that case you need to modify Hash, not String. Below is
some code which does that.
---- 8< ----
# Extend a Hash with this module to get semantics of a Javascript
object:
# me.foo is the same as me['foo']
module JSObjectMixin
def method_missing(meth,*rest,&blk)
key = meth.to_s
if key[-1] == ?=
self[key[0..-2]] = rest.first
else
self[key]
end
end
end
def extend_jsobject(tree)
case tree
when Hash
tree.extend JSObjectMixin
tree.each do |k,v|
extend_jsobject(v)
end
when Array
tree.each do |v|
extend_jsobject(v)
end
end
end
errors = [{"suggestions"=>{"option"=>["really", "ready", "real",
"relay",
"realty"]}, "precontext"=>"I'm", "type"=>"spelling",
"string"=>"realy",
"description"=>"Spelling"}, {"suggestions"=>{"option"=>["weather",
"whether"]},
"url"=>"
http://service.afterthedeadline.com/info.slp?text=we...
,
"precontext"=>"this", "type"=>"spelling", "string"=>"wether",
"description"=>"Did you mean..."}]
extend_jsobject(errors)
errors.each { |error| p error['string'] }
errors.each { |error| p error.string }
---- 8< ----
Another option would be to walk your results structure and replace each
Hash with an OpenStruct (see ostruct.rb in the standard library).
However, that would _only_ allow error.string, not error['string']
> The other problem I'm having with the way I'm doing it now is that
> calling .errors.each when there's only one error sent back gives me a
> "can't convert String into Integer" error.
Simple solution:
Array(atd.errors).each { ... }
If atd.errors is already an Array this does nothing; if it isn't, then
it is wrapped in a one-element array.
Better solution: If this is using XML::Simple internally, there's an
option you can give it to return arrays always, even when there's only a
single instance (or I believe you can tell it to do this for specific
tags). I can't remember offhand what that option is, but you should be
able to find it. Then see if the library you're using allows that option
to be passed through.
HTH,
Brian.
--
Posted via
http://www.ruby-...
.
Servizio di avviso nuovi messaggi
Ricevi direttamente nella tua mail i nuovi messaggi per
Defining a method to select values from a hash.
Inserendo la tua e-mail nella casella sotto, riceverai un avviso tramite posta elettronica ogni volta che il motore di ricerca troverà un nuovo messaggio per te
Il servizio è completamente GRATUITO!
x
Login to ForumsZone
Login with Google
Login with E-Mail & Password