The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Object templates in Ruby

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Aslak Hellesøy

Posts: 29
Nickname: aslak
Registered: Mar, 2005

Aslak Hellesoy is a senior developer for ThoughtWorks, Inc.
Object templates in Ruby Posted: Mar 9, 2005 5:11 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Aslak Hellesøy.
Original Post: Object templates in Ruby
Feed Title: Aslak Hellesøy's uncommon sense
Feed URL: http://aslakhellesoy.com/rss
Feed Description: Ruby-related blog posts from Aslak Hellesøy
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Aslak Hellesøy
Latest Posts From Aslak Hellesøy's uncommon sense

Advertisement

The concept of templates are very common in many contexts of programming. A boiler-plate representation of something can be turned into a concrete instance by supplying some extra data. The important point is that the supplied data can vary, and that has an impact on the structure of the concrete instance of the template.

In HTML programming, common template techniques are JSP, PHP, ERB and ASP. By passing some extra data to a template engine, a template can be turned into an HTML page that displays the data, using the layout from the template.

In OO programming, the most common concept of a template is a Class. A piece of a program can supply some data to a class' constructor and get a new object.

Sometimes, instantiating a new object by simply calling a constructor with some extra data is not the optimal way to create an object though. Consider the common situation where the desired object is composed of an aggregation of several other objects. -A complex graph of objects.

One way to approach this is to design classes (aka templates) to honour Dependency Injection (DI), and use a DI container supporting a configuration file (in XML or other format). NanoContainer or Spring are two frameworks that use this approach to instantiate complex graphs of objects composed of "variable data" from a configuration file.

Assuming you want the ability to create object graphs that are configured in an external file, and your language is Java, then it doesn't get much simpler than with NanoContainer or Spring.

But in Ruby...

A similar effect that is radically simpler and extremely easy to use can be achieved with a dash of Ruby magic using YAML and eval under the covers. Consider this object template:

codehaus_project_template = Project.new codehaus_project_template.home_page = "http://\#{unix_name}.codehaus.org" jabber_publisher = JabberPublisher.new jabber_publisher.id_resource = "damagecontrol@jabber.codehaus.org/#{unix_name}" codehaus_project_template.publishers << jabber_publisher (The template object can also be deserialised from a YAML file if we don't wish to do this in Ruby code, but this is not important from the perspective of describing how this object template technique works). The point I'm getting at is that I can create new instances from this template object like this: project = codehaus_project_template.dupe("unix_name" => "mooky") assert_equal("http://mooky.codehaus.org", project.home_page); assert_equal("damagecontrol@jabber.codehaus.org/mooky", project.publishers[0].id_resource); The dupe method takes a Hash that should have one key/value pair for each variable in the object template. The dupe method simply creates a new object graph similar to the one in the template, but substitutes all variables with the values from the hash. -All the way out to the leaves of the object graph! The object template's variables are simply backslash-escaped #{blah} s in various String instance variable values (fields). In the example there is only one (#{unix_name}), but we could use as many as we like, at any level in our object graph. In Ruby it's ridiculously easy to make this happen. Just make the classes whose instances you want to use as templates include ObjectTemplate: module ObjectTemplate def dupe(variables) template_yaml = YAML::dump(self) b = binding variables.each { |key, value| eval "#{key} = variables[\"#{key}\"]", b } new_yaml = eval(template_yaml.dump.gsub(/\\#/, "#"), b) YAML::load(new_yaml) end end A similar approach can be achieved in Java with XStream and Velocity (or Jelly, haha) and maybe a little bit of AOP - in 10 times or more as many lines of code - without the same ease of use.

Read: Object templates in Ruby

Topic: &#8220;What the fuck are we gonna do now?!&#8221; Previous Topic   Next Topic Topic: Mix Tape Suspended

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use