Skip to main content

Meta-programming In Ruby

Last Wednesday (08.27.2008), I attended a presentation given by local ruby "hero" Joe O'Brien. He was presenting techniques for meta-programming in Ruby. Meta-programming is a general topic which applies to many languages, however Ruby provides some very basic methods which result in powerful meta-programming tools for creating dynamic run-time functionality and for enhancing the base language.

Meta-programming Methods

Joe started the presentation with a run-down of some of the meta-programming methods exposed by the base object in Ruby.

  • send--By using the send method with a string value (method name) and a list of parameters you can dynamically choose a method to call. This method is provided in conjunction with the message-passing back-bone used by the Ruby interpreter.
  • method_missing--Implementations of the method_missing message handler can be used to handle messages which are currently not understood by the receiving object. This is an expensive method to use, but can be used to add new functionality in response to an unknown message. ActiveRecord in Rails uses this method to create finder methods when a search is performed.
  • eval--Evaluate a string value as arbitrary Ruby code. User beware Since this method takes a string argument as the code to be evaluated, any code in that string is not checked by the interpreter until the eval statement is executed by the interpreter.
  • define_method--Pass a string value (method name) and a block in order to define a new method defined by the given block. This method takes a block as a parameter and is safer to use than the eval method.
  • methods--Returns an array of the methods currently defined on an object. By calling methods on an object and subtracting the result of calling methods on that object's supertype, you can easily get a list of the methods defined only within that object.
  • attr_reader--The attr_reader method is used to make a private field in an object accessible to other objects.
  • attr_writer--The attr_writer method is used to make a private field in an object settable by other objects.
  • attr_accessor--The attr_accessor method is used to make a private field in an object accessible and settable by other objects.

Example: Declarative Tests and Home-Grown Behavior Driven Development

Joe, being a "test-first bigot" (his words, not mine), was uncomfortable with the idea that it took him nearly 10 lines of code to test one ActiveRecord has_many association. He also expressed his dislike for creating test methods whose names look like test_a_description_of_the_test. His iterative approach to creating a declarative version of this this test method started with the original 10 lines of code in his test method. He extracted that method into a method on the Test::Unit::TestCase class, test_that, which took three arguments, the model under test, the expected has_many association class, and a description of the test as a string. These parameters were used in conjunction with the define_method method to create a new method at run-time which executed the original code. Using this technique, Joe stated that he was able to reduce the tests for many of the ActiveRecord capabilites to one-liners.

Comments

Popular posts from this blog

Using MonoDevelop to Create an ASP.NET Web Service

NOTE: instructions below are for MonoDevelop 2.6 Beta 2 - built on 2011-04-06 03:37:58+0000Getting StartedCreate a new ASP.NET Web Application in MonoDevelop: From the menu, select: File → New → Solution…Expand C#.Select ASP.NET → Web Application.Enter a name for the ASP.NET project that will be created in the solution in Name:.Change the root location for the solution in Location:, if desired.Change the name of the root solution in Solution Name:, if desired.The Results – IWhat you have after executing the new ASP.NET Web Application project wizard is a solution containing one ASP.NET Web Application project. In the default project view in MonoDevelop, you'll find the following items: Default.aspx – This is the default web form rendered and presented in the browser when http://<server>:<port>/ is accessed. Default.aspx.cs – This C# file contains the developer-created common code and event handlers which can be used to affect the processing of the form.Default.aspx.des…

Testing Toolbelt: SpringJUnit4ClassRunner

The org.springframework.test.context.junit4.SpringJUnit4ClassRunner class is another implementation of the JUnit TestRunner class which is used to enable various features of Spring for every run of the test class and every test within it. To use the features provided by the SpringJUnit4ClassRunner class, you need to mark the class using the RunWith annotation using SpringJUnit4ClassRunner as its parameter.In addition to the custom test runner, you will want to mark the class with the ContextConfiguration annotation. The ContextConfiguration annotation is used to mark classes which will automatically read a Spring configuration file and use it to create an ApplicationContext. By default, this file located at <package path>/<test class name>-context.xml. Use the locations argument to over-ride.The ApplicationContext used by the Spring-integrated test will only be loaded once for the whole test class. This behavior can be over-ridden by annotating a test method with the Dirti…