In my talk at Full Stack Fest I showed how to recreate some fundamental Ruby functionality in a pure OO way, building numbers, conditional logic and strings. However I didn't have to show how to build everything and there are a number of interesting features I didn't explore. This repo contains some fun challenges to build some of the missing functionality.
The challenges are all pretty short. I don't know how long it will take you to do them, but none of them require much code. They're mostly tricky little brain teasers. I hope you have fun solving them.
Please create a Pull Request if you solve any/all of them, or if you get stuck. I'm happy to give you some feedback and I'll update this README to share any interesting solutions.
There is a file called test.rb that you can use to check your solutions. If everything works then it will print "OK" a lot. If it doesn't work then you might occasionally get weird errors.
And now ladies and gentlemen, without any further ado, I give you The Challenges.
Numbers in a pure OO version of Ruby work by creating a class to represent Zero, and another class to represent other positive integers as the number of successors to Zero. This idea comes from the Italian mathematician Guiseppe Peano.
Performing addition using this approach requires us to count the number of successors from Zero for one of the numbers, and call the successor function on the other number that number of times. Another way to put this is that we count down to Zero from one of the numbers, counting up away from Zero the same number of steps for the other number.
Implementing this in pure OO ruby uses two short methods: one on the NumberZero and one on other numbers. The implementation is:
class NumberZero
def +(other)
other
end
end
class Number
def +(other)
(@pred + other).succ
end
end
I didn't have time to talk about how to implement pure OO lists, so these challenges are all about how to implement them. Like most of these challenges, lists are easy to implement once you know how to do them. Until that point they may prove to be illusive.
Implement solutions to this in a file called 'list.rb' if you want to run the tests.
I imagine you would use the list as follows:
list = List.new
list.append("first") # or if you prefer: list << "first"
list.append("second")
list.inspect # => "first", "second",
This might seem a little daunting. If you don't know how to get started then the following sub-challenges might help break the problem down for you.
This item should store a single value, and hold a reference to the next item in the list.
This wouldn't do much (yet), but it represents the 'next item' when there is no next item.
I would expect to be able to do something like this:
list = List.new
list.append("first")
list.append("second")
list[Zero] # => "first"
list[One] # => "second"
list[Two] # => some indication that the index is invalid
I needed to understand numbers, number equality and conditional logic
- including the problem of delayed execution - to make this work.
Lists are really a special case of a hash, where the 'keys' are numbers in sequential order. We can replace our list implementation with a generic hash (or map, if you prefer) that allows us to store and retrieve values using some arbitrary key.
Implement solutions in a file called 'map.rb' if you want to run the tests. I expect to be able to use it similar to the following:
map = Map.new
map[One] = True.new
map[False.new] = Seven
map[One] # => True.new
map[False.new] # => Seven