Here’s what I’m doing:
offers = v.offers.sort { |a,b| a.expires <=> b.expires }
This data is loaded via ActiveResource (so each set of instance attributes is defined by the data it contains). However, a recent change in the incoming data has made the “expires” attribute optional. Is there a class definition change that will cause the sort method to go grab a default value if the attribute is missing from an instance?
edit: @Nikita
It looks like it won’t be that simple:
o.expires == nil?
NoMethodError: undefined method `expires' for #<Offer:0x00000100d3faa8>
o.expires?
=> nil
so I tried:
offers.sort{|a,b|
if a.expires?
b.expires? ? 0 : -1
else
b.expires? ? 1 : a.expires <=> b.expires
end
}
NoMethodError: undefined method `expires' for #<Offer:0x00000100d3faa8>
I was hoping to be able to update the class definition with something like:
expires ||= ""
… but I don’t know if that’s possible. I don’t really follow how the sorting blocks work yet, though. I know I could just loop through the offers and assign the value, but it seems grossly inefficient.
update
offers.sort{|a,b|
if defined? a.expires == nil
(defined? b.expires == nil) ? 0 : -1
else
(defined? b.expires == nil) ? 1 : a.expires <=> b.expires
end
}
ArgumentError: comparison of Offer with Offer failed
from (irb):70:in `sort'
from (irb):70
from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.0.0.beta4/lib/rails/commands/console.rb:47:in `start'
from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.0.0.beta4/lib/rails/commands/console.rb:8:in `start'
from /usr/local/lib/ruby/gems/1.9.1/gems/railties-3.0.0.beta4/lib/rails/commands.rb:23:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
Hooray for verbosity ;p
I don’t get what ‘class definition’ you want. Won’t just adapting sort block solve the problem?
on update
I see. There’s a
defined?operator in ruby which might help. It returns nil or string representing type of element (like ‘method’).I don’t really follow how the sorting blocks work yet, though.
That’s easy. It should return -1, 0 or 1 depending on whether first element is smaller, equal or bigger than second.
<=>operator does more or less the same thing:update again
Works for me
Your error indicates that
a.expireshas typeOffer, which can’t be compared.Hooray for verbosity ;p
Welcome to rails 🙂