- Read Tutorial
- Watch Guide Video
As you can see here we have a few different test cases.
One of them looks really weird and it's because we were working with exponents and exponents can grow quite a bit. And I wanted to have some solid test coverage for this function. So what we have here is you can see that with the expected behavior is that we should be able to call a number and then pass the method, to the power of, to that and then pass in an argument of what we want the exponent to be.
So I'm going to give you a little bit of a hint before you pause the video and try to build this out, and that is that we have to open up the integer class in order to make this possible. Remember that any time they want to perform a task like this where you want to pass a method directly to an integer or in if you needed to do it to a string then you'd have to open up the String class or the array then you'd have to open up the array class and so on and so forth. But because the structures like this we're going to have to open up the integer class in order to get all of the tasks passing.
Now as far as the behavior that we're looking for, it's pretty standard exponent behavior. So we should have the same kind of behavior as if we just said 2 to the power of 3. We expect this to equal 8. Just like you would see in those other test cases 3 to the power of 5 should equal to 43 and then 10 to the power of 120 should equal whatever that giant number right there is. So that is what your task is. I recommend that you pause the video right now, try to build this out yourself and then come back and watch my solution.
So if you built that out congratulations! There are a number of ways to do this, and so the solution that I'm going to go with takes advantage of a couple different functional tools inside of Ruby. So I'm going to create this function inside of the integer class and I'm going to say to the power of. And then pass in exp as the argument we're expecting here and then I'm going to because of the way inject is going to work here, I'm going to say exponent minus one. And the reason for that is because I'm going to use the inject method and inject is going to have the default of the first value.
So if you do not subtract one from the exponent then you're going to multiply the value one too many times. And so here I'm going to say exponent minus one times. So I want whatever the exponent is I want this entire process to run as many times as we have there and then I'm gonna say dot inject. So this is similar if you're coming from another language. This may also be called reduce in those other language but I went I'm going to be doing is I'm going to be passing inject then I'm going to be grabbing self.
require 'rspec' class Integer def to_the_power_of(exp) (exp - 1).time.inject(self) end end
Now if you're not used to Ruby and opening up classes what self is going to be referencing is the instance of the class. So, in this case, it's the instance of the integer class and if you come down to our test cases what that means is that in this example self is going to be 2, in this example self is going to be 3, and in this example self is going to be 10.
So that's all self is right there, I know that looks a little confusing if you've never used it before but it is going to have a direct reference to the instance of the class we're working on. And from there I'm going to pass a code block and we're going to this is something specific to inject. I'm going to have a total which is going to be our accumulator. This is going to accumulate the values and then it's going to simply have an element that is the value element but I want to ignore it and any time that you want to ignore something that's a required element as a block variable.
The common convention is to use an underscore this is just a sign to anyone reading the code that you needed to have some kind of placeholder there but you're not actually going to use it. In a regular inject kind of situation, you would probably use this value. You'd call it something like element or something like that because you'd want to know what that value is. But in our case we already know all the values are going to be the same, they're all going to be in that first case 2, in the next case all the values are going to be 3, and then the last one all the values are going to be 10.
What I'm going to do here is say total and then multiply that and set it equal to the value of total times self. And so this is the reason why we didn't need that value here because we're grabbing self each time and then we're simply multiplying it and incrementing the value of total and we can test this out right here. So if I say 2 to the power of and say 3 if I want to see this than this equals 8 so that's working perfectly.
If I change this to 5 and let's run it again, now the value is 125 so that's working exactly the way that you'd expect an exponent to work.
So great job if you went through that! Now you know how to manually build out an exponent in Ruby and just to make sure everything's working and all of our test cases are working. Let's run the tests and there you go. We have one example zero failures and everything is working and we have our own manual exponent method in Ruby.