Skip to content

Instantly share code, notes, and snippets.

@bkeepers
Last active December 19, 2015 18:58
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bkeepers/6002211 to your computer and use it in GitHub Desktop.
Save bkeepers/6002211 to your computer and use it in GitHub Desktop.
I'm looking for a better pattern for defining a method that takes a single object or an array of objects as an argument, does something with them, and then returns either a single object or an Array depending on what was passed to it.
def dress(dog_or_dogs)
dressed_dogs = Array(dog_or_dogs).map {|dog| DogSweater.new(dog) }
dog_or_dogs.respond_to?(:each) ? dressed_dogs : dressed_dogs.first
end
one_dog = dress(Dog.new)
all_my_dogs = dress([Dog.new, Dog.new, Dog.new])
@teleological
Copy link

def dress(*dogs)
  dogs.size == 1 ? dress_dog(dogs[0]) : dogs.map { |dog| dress_dog(dog) }
end

def dress_dog(dog)
  DogSweater.new(dog)
end

dressed_dog = dress(Dog.new)
dressed_dogs = dress(Dog.new, Dog.new, Dog.new)
more_dressed_dogs = dress(*other_dogs)

@dchelimsky
Copy link

I'm looking for a better pattern for defining a method that takes a single object or an array of objects as an argument

Don't? Why not just UTFL™?

all_my_dogs = [Dog.new, Dog.new, Dog.new].map(&:dress)

This uses core functionality of the language to handle a core function (do something to every element in this collection and return the collection) and doesn't require that I understand the meaning of different inputs to dress. All for the modest cost of 6 additional characters.

@ungarst
Copy link

ungarst commented Jul 15, 2013

@rjackson why call dress from within dress_all rather than dress_one. Calling dress one seems simpler to me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment