1. What is Monkey patch
- Is a feature of ruby that allows you to edit an existing function or add a new function to any class.
a. Add a new method to the class
- The following code will raise the error
NoMethodError (undefined method shuffle for "aaa":String)
12<span class="token string">"monkey patch"</span> <span class="token punctuation">.</span> shuffle - The reason is that the
String
class has noshuffle
method - We can use monkey path to add the
shuffle
method to theString
class123456789<span class="token keyword">class</span> <span class="token class-name">String</span><span class="token keyword">def</span> <span class="token method-definition"><span class="token function">shuffle</span></span><span class="token keyword">self</span> <span class="token punctuation">.</span> chars <span class="token punctuation">.</span> shuffle <span class="token punctuation">.</span> join<span class="token keyword">end</span><span class="token keyword">end</span>puts <span class="token string">"monkey patch"</span> <span class="token punctuation">.</span> shuffle<span class="token comment"># n ptchemkyao</span>
b. Modify the method available in the class
- Similarly we can also use monkey path to edit methods available in class
- For example123456789<span class="token keyword">class</span> <span class="token class-name">String</span><span class="token keyword">def</span> <span class="token method-definition"><span class="token function">length</span></span><span class="token number">100</span><span class="token keyword">end</span><span class="token keyword">end</span>puts <span class="token string">"monkey patch"</span> <span class="token punctuation">.</span> length<span class="token comment"># 100</span>
2. How to organize code with monkey patch
- Monkey patch is a powerful tool that can also cause errors and debugging if not used and well organized.
- In the above examples I have monkey path directly into the class
- It is not a good way for the following reasons.
i. The code will be overridden
- When a method has 2 monkey-paths, the second path will overide the 1st path and affect the code that runs on the 1st path.
- For example:123456789101112131415161718<span class="token keyword">class</span> <span class="token class-name">String</span><span class="token keyword">def</span> <span class="token method-definition"><span class="token function">length</span></span><span class="token number">100</span><span class="token keyword">end</span><span class="token keyword">end</span>puts <span class="token string">"monkey patch"</span> <span class="token punctuation">.</span> length<span class="token comment"># 100</span><span class="token keyword">class</span> <span class="token class-name">String</span><span class="token keyword">def</span> <span class="token method-definition"><span class="token function">length</span></span><span class="token number">200</span><span class="token keyword">end</span><span class="token keyword">end</span>puts <span class="token string">"monkey patch"</span> <span class="token punctuation">.</span> length<span class="token comment"># 200</span>
ii. Can’t handle whether I’m using monkey path or not
- When you don’t want to use monky-path, you only have to re-comment the monkey path code
- However, doing so will affect the code that is running correctly with monkey path
iii. Solution
- Use the module containing monkey path and include only when needing to use monkey path
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <span class="token keyword">module</span> <span class="token constant">CoreExtensions</span> <span class="token keyword">module</span> <span class="token builtin">String</span> <span class="token keyword">module</span> <span class="token constant">MonkeyPath</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">shuffle</span></span> <span class="token keyword">self</span> <span class="token punctuation">.</span> chars <span class="token punctuation">.</span> shuffle <span class="token punctuation">.</span> join <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token builtin">String</span> <span class="token punctuation">.</span> <span class="token keyword">include</span> <span class="token constant">CoreExtensions</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token builtin">String</span> <span class="token punctuation">:</span> <span class="token punctuation">:</span> <span class="token constant">MonkeyPath</span> puts <span class="token string">"monkey patch"</span> <span class="token punctuation">.</span> shuffle |