I notice in Ruby it is very common to for vendor APIs to pass back results as arrays? Shouldn't Plain Old Objects (Like POJOs in Java) be more of a standard? If I write my own library shouldn't I use POJOs POROs?
views:
160answers:
4I think array vs object is a false dichotomy.
It is perfectly reasonable, where an API call is returning more than one of a thing, that it is in the form of an array (and an array is a fairly simple object, and therefore arguably a 'PORO', in Ruby anyway)
Edit: in response to your comments:
The example you cite ( http://github.com/cjheath/geoip ) returns an array of differing items. I agree this is not necessarily the best format to return the data in. In that case I would have thought a hash with sensibly named keys would be a better structure.
As John Topley says, the OO nature of Ruby means people don't have to invent such terminology as 'PORO', as a hash is pretty much as simple as you can get.
What do those arrays of results contain? The answer is that in Ruby they contain objects, because everything in Ruby is an object.
POJOs in the Java world were a reaction against some of the complexities inflicted upon the world by enterprise Java e.g. EJBs. To quote Martin Fowler who coined the term:
"We wondered why people were so against using regular objects in their systems and concluded that it was because simple objects lacked a fancy name. So we gave them one, and it's caught on very nicely."
Fortunately in Ruby it has always been natural for people to just practise object-oriented programming without the need to invent terminologies around it.
I personally use POROs in almost anything I write that isn't a complete throwaway script.
I find myself often creating a data holder type of class that would manage and hold multiple objects of my specific type and include some helper methods. I find this convenient for when someone else has to work with my code as well.
I think this question is very subjective in the sense that there isn't an answer that is always right. Sometimes just passing back an array is fine and there is no need to create an extra class. Sometimes the extra level of abstraction makes something a lot more clear to the user.
It's all objects, all the time. The key is whether the objects being returned have behavior associated with them. It's fine to do this:
def read_first_and_last_name(data_source)
[data_source.read_string, data_source.read_string]
end
But the moment you find there is behavior associated with those data items...
def print_name(first_name, last_name)
puts "#{first_name} #{last_name}"
end
def read_and_print_name
first_name, last_name = read_first_and_last_name(data_source)
print_name(first_name, last_name)
end
...then they should be a class:
class FullName
def FullName.read(data_source)
FullName.new(data_source.read_string, data_source.read_strng)
end
def initialize(first_name, last_name)
@first_name = first_name
@last_name = last_name
end
def print
puts "#{@first_name} #{@last_name}"
end
end
With a name's behavior nicely encapsulated, usage becomes as simple as:
def read_and_print_name
FullName.read(data_source).print
end