avdi + metaprogramming 10
Mirrors: Design Principles for Meta-level Facilities of Object-Oriented Programming Languages
february 2012 by avdi
Thought-provoking read on using Mirrors for language reflection, via @joshsusser
metaprogramming
reflection
oo
oop
programming
languages
self
smalltalk
clos
lisp
c#
java
february 2012 by avdi
Ara T. Howard's "shared" library
november 2008 by avdi
A library for making mixin modules easier.
sharing
ruby
development
modules
mixins
metaprogramming
libraries
november 2008 by avdi
Extend modules instead of defining methods on a metaclass
april 2008 by avdi
In the entry Replace method_missing with dynamic method definitions I have the following example code.class Decorator def initialize(subject) subject.public_methods(false).each do |meth| (class << self; self; end).class_eval do define_method meth do |*args| subject.send meth, *args end end end endendThe context of the example can be summarized as, you want to delegate from the instance all the public methods defined on the constructor argument.Ali Aghareza pointed out to me that defining methods on the metaclass of an instance isn't the nicest thing to do. The problem with it is that you've made it much harder for anyone else to change the behavior of the instance.Here's a more simplified example. The following code creates a new Object and defines the hello_world method on the Object instance.class Object def metaclass class << self; self; end endendobj = Object.newobj.metaclass.class_eval do def hello_world "hello" endendobj.hello_world # => "hello"This works fine; however, if someone wanted to change the way hello_world behaved, by defining the method on the metaclass you force them to make their change by redefining the method on the metaclass. The current solution does not allow you to extend modules and alter the behavior of the instance.The following example demonstrates that extending a module does not change the behavior of an instance if the behavior has been defined on the metaclass.class Object def metaclass class << self; self; end endendobj = Object.newobj.metaclass.class_eval do def hello_world "hello" endendobj.hello_world # => "hello"module Spanish def hello_world "hola" endendobj.extend Spanishobj.hello_world # => "hello"A better solution is to change the behavior of the instance by extending modules instead of defining behavior on the metaclass.obj = Object.newmodule English def hello_world "hello" endendobj.extend(English).hello_world # => "hello"Now that the behavior is defined on an ancestor instead of the metaclass you can change the behavior by extending another module.obj = Object.newmodule English def hello_world "hello" endendobj.extend(English).hello_world # => "hello"module Spanish def hello_world "hola" endendobj.extend(Spanish).hello_world # => "hola"This solution works fine for our simple example, but it can also be applied to our first (much more complicated) example, even without knowing how to define the module. In the case of the Decorator, you can simply define an anonymous module and immediately extend it.class Decorator def initialize(subject) mod = Module.new do subject.public_methods(false).each do |meth| define_method meth do |*args| subject.send meth, *args end end end extend mod endend© Jay Fields - www.jayfields.com
define_method
def
metaprogramming
metaclass
from google
april 2008 by avdi
related tags
c# ⊕ c++ ⊕ clos ⊕ def ⊕ define_method ⊕ development ⊕ dom ⊕ gems ⊕ generator ⊕ guide ⊕ howto ⊕ java ⊕ language ⊕ languages ⊕ libraries ⊕ lisp ⊕ metaclass ⊕ metaprogramming ⊖ mixins ⊕ modules ⊕ mop ⊕ oo ⊕ oop ⊕ parser ⊕ programming ⊕ reflection ⊕ ruby ⊕ self ⊕ sharing ⊕ smalltalk ⊕ techniques ⊕ tool ⊕ transformation ⊕Copy this bookmark: