Inject: Ruby's Fold

In this episode, Ben and Joe tackle a highly useful but lesser known method from Ruby's Enumerable module: inject. While watching, you'll see how inject is just an abstraction over certain types of recursion. We'll use examples to demonstrate inj...
This is a companion discussion topic for the original entry at https://thoughtbot.com/upcase/videos/inject-ruby-s-fold
1 Like

I have a question about the first example in the video on Inject:

def sum(array)
  element, *rest = array
  ...
end

so I understand that *rest is taking all the elements of array except the first one, but what is ‘rest’, is it a new array or is it a list?

Thanks for the explanation,

Anthony

Hey Anthony,
rest is an array.
Not sure we use the list terminology in Ruby.
I played around with the code below to grasp what is going on.
Does it help ?

def sum(array)
	element, *rest = array
	case rest
	when []
		element
	else
		puts "Array per recursion: #{rest.inspect}"
		element + sum(rest)
	end
end

result = sum([1,87,3,4,-5,-48])
puts "Result : #{result}"

yeah, I tried out the program in irb:

Array per recursion: [87, 3, 4, -5, -48]
Array per recursion: [3, 4, -5, -48]
Array per recursion: [4, -5, -48]
Array per recursion: [-5, -48]
Array per recursion: [-48]
=> 42 

it works :smile:

In 'The Well-Grounded Rubyist" I read something about a 'bare list", hence my question.

greetings,

Anthony

When I work with less-experienced developers, I find that using #inject is usually a technique that not only are they not using, but haven’t even considered. +1 for promoting it!

1 Like

I had a hard time learning the #inject method, I started this post a while ago when trying to figure it out, there is some useful information on there, that helped me a lot and also a video demonstraiting how it works.

I would really like to see a practical implementation of this in an app tutorial sometime :smile:

Joe is actually working on creating an exercise with a number of practical examples. It should be hitting your dashboard within a week or so.

3 Likes

I will be looking forward to that.

Just used reduce to refactor some code I saw on a blog post.

def filter(filtering_params)
  results = self
  filtering_params.each do |key, value|
    results = results.public_send(key, value) if value.present?
  end
  results
end

became

def filter(filtering_params)
  filtering_params.reduce(self) do |relation, (scope_name, value)|
    relation.public_send(scope_name, value) if value.present?
  end
end

I thought others might interested in seeing some random ruby code refactored to use reduce. Also notice how it works nicely with the builder pattern.

Thanks, this was a great video tutorial.