Simple Monkey Patching

BakaCoder

Warper
Member
Joined
Nov 18, 2013
Messages
4
Reaction score
3
First Language
Chinese
Primarily Uses
Simple Monkey Patching - v0.5​
I am tired of aliasing​
 ​
 ​
The Default Way of Monkey Patching:
class Scene_Base alias monkeypatch_demo_sb_init initialize def initialize monkeypatch_demo_sb_init puts "A Scene Has Been Initiliazed!" endendWhy do we need all these aliases?

The Simple Way:
class Scene_Base monkeypatch :initialize do puts "A Scene Has Been Initialized!" endendThis is much better  B)

Normal Usages:
Code:
class WhateverClass  monkeypatch :method_name do    #whatever you want to do ._.  endend
Code:
class Scene_Base  monkeypatch :initialize, :before do    puts "This is called before the original scripts"  endend
Installation
get the script here: http://pastebin.com/zgQe4HWH
insert this before all scripts that uses this type of monkey-patching.​
 ​
Possible Updates
I really don't like the naming of the aliases._.. Maybe I will improve it later.​
You still cannot call the original return value._., maybe you can later.​
 ​
Known Bugs
Currently None, but there is a high possibility that there are some  >_>
 ​
Terms of Use
You can repost this anywhere else without my permission.​
You can modify the script as long as you keep my name on it.​
Credit Me.  ​
 

IceDragon

Elder Cookie Dragon
Veteran
Joined
Mar 8, 2012
Messages
73
Reaction score
63
First Language
English
Primarily Uses
N/A
Nice idea, I like,

However a few problems:

1. Don't use global variables to store context sensitive functions.

2. there is a chance (1 out 9998) that you will alias an already aliased functions (resulting in that rather scary SystemStackError) if you end up calling it

3. You can shorten this code quite a bit

4. My take:

#===============================================================================# Monkeypatch v 0.5 by BakaCoder aka XXX#===============================================================================# monkeypatch <method_name (sym)> (&block)#===============================================================================proc do# Example class Scene_Base patch :initialize do puts "A Scene has been initialized!" end end# Endend module MonkeyPatch def monkeypatch(sym, pos=:after, &block) meth = instance_method(sym) # original method define_method(sym, &block) meth2 = instance_method(sym) # alias method if pos == :after define_method(sym) do |*a, &b| meth.bind(self).call(*a, & meth2.bind(self).call(*a, & end else define_method(sym) do |*a, &b| meth2.bind(self).call(*a, & meth.bind(self).call(*a, & end end end alias :patch :monkeypatch end class Module include MonkeyPatchendBy using UnboundMethodBy the way, I've added this edit to my kode-xchange, :) if you don't mind.
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
How would I do something like this using your monkey patch method

Code:
alias :old_method :methoddef method  # do something here  res = old_method  # do something with the resend
It definitely saves me from having to come up with an aliased method name though, especially since it can become arbitrarily lengthy.
 
Last edited by a moderator:

IceDragon

Elder Cookie Dragon
Veteran
Joined
Mar 8, 2012
Messages
73
Reaction score
63
First Language
English
Primarily Uses
N/A
Could be done by adding a third option for patch-ing (aka chaining)

Right, just make it the second arg.

patch :method_name, :chain do |result_from_original_method| do_stuffendUpdate:
Code:
#===============================================================================#  Monkeypatch v 0.5 by BakaCoder aka XXX#  rewritten by IceDragon#===============================================================================# monkeypatch <method_name (sym)> (&block)#===============================================================================proc do# Example  class Scene_Base    patch :initialize do      puts "A Scene has been initialized!"    end    patch :initialize, :before do      puts "Scene #{self.class.name} initializing"    end  end  class Something    def sum      1 + 1    end    patch :sum, :chain do |oldsum|      oldsum + 1    end  end# Endendmodule MonkeyPatch  def monkeypatch(sym, pos=:after, &block)    meth = instance_method(sym) # original method    define_method(sym, &block)    meth2 = instance_method(sym) # alias method    case pos    when :after      define_method(sym) do |*a, &b|        meth.bind(self).call(*a, &        meth2.bind(self).call(*a, &      end    when :before      define_method(sym) do |*a, &b|        meth2.bind(self).call(*a, &        meth.bind(self).call(*a, &      end    when :chain      define_method(sym) do |*a, &b|        meth2.bind(self).call(meth.bind(self).call(*a, &, *a, &      end    end  end  alias :patch :monkeypatchendclass Module  include MonkeyPatchend
I feel I've hijacked this thread... :x
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,564
Reaction score
3,846
First Language
English
That makes it easier, especially being able to control when the old method should be called.

Very often I do things like this as well

Code:
def test  @value += 20endalias :old_test :testdef test  @value = new_value  # :before  old_test  @value *= 2         # :after  return @valueend
So I can use a :before and an :after to accomplish this.
 
Last edited by a moderator:

BakaCoder

Warper
Member
Joined
Nov 18, 2013
Messages
4
Reaction score
3
First Language
Chinese
Primarily Uses
Could be done by adding a third option for patch-ing (aka chaining)

Right, just make it the second arg.

patch :method_name, :chain do |result_from_original_method| do_stuffendUpdate:
Code:
#===============================================================================#  Monkeypatch v 0.5 by BakaCoder aka XXX#  rewritten by IceDragon#===============================================================================# monkeypatch <method_name (sym)> (&block)#===============================================================================proc do# Example  class Scene_Base    patch :initialize do      puts "A Scene has been initialized!"    end    patch :initialize, :before do      puts "Scene #{self.class.name} initializing"    end  end  class Something    def sum      1 + 1    end    patch :sum, :chain do |oldsum|      oldsum + 1    end  end# Endendmodule MonkeyPatch  def monkeypatch(sym, pos=:after, &block)    meth = instance_method(sym) # original method    define_method(sym, &block)    meth2 = instance_method(sym) # alias method    case pos    when :after      define_method(sym) do |*a, &b|        meth.bind(self).call(*a, &        meth2.bind(self).call(*a, &      end    when :before      define_method(sym) do |*a, &b|        meth2.bind(self).call(*a, &        meth.bind(self).call(*a, &      end    when :chain      define_method(sym) do |*a, &b|        meth2.bind(self).call(meth.bind(self).call(*a, &, *a, &      end    end  end  alias :patch :monkeypatchendclass Module  include MonkeyPatchend
I feel I've hijacked this thread... :x
Actually this is much more better. Having someone that is better than me in ruby is so much better :) . I really like this way to call the original return value. Anyway, thank you very much.
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.
Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD
How many parameters is 'too many'??

Forum statistics

Threads
105,865
Messages
1,017,059
Members
137,575
Latest member
akekaphol101
Top