Wednesday, 07. February 2007

ruby ruminations - singleton class

some call it singleton class, some metaclass or even eigenclass.
in this blog entry i will give some explanation about the concept of singleton class (which i will call it during this post) and some (more or less useful) examples of its application.

you're one-of-a-kind

as you may know, ruby lets you enhance single objects by adding a new method to just one instance of an arbitrary class, leveraging this specific object to a real 'singleton' (in another sense, in contrast to the well known singleton pattern). since all methods are defined and housed in the objects class', such new added methods also have to be 'append' to and hence reside in the objects class.

lets say we want to add a  method palindrome? to only one specific instance of a string:

 
aString = "never odd or even"

class << aString
  def palindrome?
    self.gsub(/\s/, '') == self.reverse.gsub(/\s/, '')
  end
end

aString.palindrome?     # => true

only this single object of String now offers this new method palindrome? (a call to any other instance of String would result in a NoMethodError)
now one could ask, where this new method is going to reside. it can't be send to the class String. if so, then all String objects would offer this method. that's where our singleton class comes into the game ...

especially for you

whenever a method is added to a single object in the above indicated way, ruby will create an extra class especially for that single object! and exactly this one is - you guessed right - our so called singleton class!

this singleton class is a virtual one, since it never appears as a fully-flegded member in the list of classes (remember that all classes are objects, which are accessible by their names as constants). ruby will insert this singleton class as the direct (again - virtual) class of the object. the former direct class - in the examples case the class String - will slide one level up, so the singleton class 'sits' between the object and the original class of the object.
now, whenever a method call (message) is send to the object, ruby will (as always) look at the direct class of the object, wheter the method is defined within that class. if so, ruby is happy and executes that method. if not, ruby will go to the ancestor (super) class (which is now the original classof the object) in order to track the message call and so on.

everywhere i go 

we now saw the mechanism of how ruby is able to add methods to single instances. going one step further we could ask ourself if it's possible to use this mechanism inside a class. we could for example offer a convenient instance method  palindromize() inside the class of String in order to add the palindrome?() method to arbitrary instances of String in a quick and easy way. and of course, it's possible:

 
class String
  def palindromize
    class << self
      def palindrome?
        self.gsub(/\s/, '') == self.reverse.gsub(/\s/, '')
      end
    end
  end
end

s = "otto"

s.respond_to?( :palindrome? )      # => false

s.palindromize

s.respond_to?( :palindrome? )      # => true

note, that we now use self to 'append' the new method. since we are inside an instance method, self refers to the object itself (on which the instance method is called) and hence the effect is the same as if you would append a new method to a single object explicitly outside a class (like in the first example)! we refer to a specific object instance in both cases.

catch me if you can

one interesting point is the scope of self inside of class << self ... end. as you may have suspected, we are in scope of that ominous singleton class, and you're right ...

 
class String
  def palindromize
    class << self   
      puts "#{self}"      # => #<Class:#<String:0x2b418e0>>
      ...    
    end
  end
end

as you can see, puts prints the 'signature' of the singleton class - in the example's case the singleton class for the String object #<String:0x2b418e0> on which the method was called.
this brings us to the point where we could dare a look at a often mentioned method (mostly even called singleton_class() or even metaclass() or eigenclass()) and understand easily what's going on there:

 
class String                       # could be an arbitrary class
  def singleton_class
    class << self; self; end
  end
end

this instance(!) method is a convenient way to access the singleton class of an object on which the method gets called. as you can see (and nothing new to us), we refer to the singleton class again (class << self), but this time not to define a new method inside the scope of that singleton class but to return the singleton class of that object itself (with self being the last evaluated expression of that method).  

i count on you

catching that singleton class as an object gives us completely new options towards a way of metaprogramming or at least a kind of generic programming. for example, it's easy to add this method inside a module together with some generic functions that operate on the singleton class of an object:

 
module Appendable

  def singleton_class
    class << self; self; end
  end

  def append_method( method_name, &prc )
     singleton_class.class_eval do
        define_method( method_name, prc )
      end  
  end
 
end

so what's going on here?
first of all we have the above mentioned method aside that allows us to refer to the singleton class of an object. we access the singleton class inside the method append_method(), which takes a method name and a proc. both arguments will constitute a new method that will be appended to a single object via its singleton class.
since we define such a method in a completely generic way in that the name of the method to append is dynamic, we use class_eval (so we can define parts of that method in a generic way and let ruby evaluate the whole expression).

now we're able to append methods very dynamic to objects of an arbitrary class which includes that module:


class Prototype
  include Appendable
end

p = Prototype.new

p.append_method( :say_hello ){|n| puts "hello #{n}" }

p.say_hello( 'Dave' )      # => hello Dave
 

using include (in contrast to extend) includes the modul's methods as instance methods. that's what we need, since we want to catch an objects singleton class. having done so enables us to append arbitrary methods to our Prototype class in a dynamic way. calling the modul's append_method(), passing a method name and a block will lead to the dynamic added method (remember, that the last argument &prc inside the argument list of append_method() will implicit call to_proc which will transfer the given block into a proc object).

no magic at all

as you've seen, there's no magic about this often mentioned singleton class, metaclass or eigenclass. it's one of rubys mechanisms which allows for dynamic programming and high flexibility.
once you have seen and understand the semantics behind these concept, it should be easy to build your own functionality on top of this instrument ...

Posted by mario.gleichmann at 23:02:43 | Permanent Link | Comments (3) |

Saturday, 27. January 2007

ruby ruminations - composing Procs

last week i had some time to play around with ruby again. in order to get deeper into it, i startet to study some foreign ruby code. amongst others, i found some very interesting libraries called ruby facets. having a look at some of their implementations caused some headache at first, but on the other side gave some motivation to understand what's happening and why it's happening in a certain way. risking a second look and having some ruminations about that code maybe gets me just a little step nearer to the white side of the force ...

this blog entry is the first one in a series of so called ruby ruminiations, where i will pick some simple looking ruby code, asking what's going on there.
i will start with a pretty small extension of class Proc, which i found in the above mentioned ruby facets core library.

now here is that little darling, asking me for some extra time to stay with'em:

class Proc
  def *(g)
  raise ArgumentError, "arity count mismatch" #...
  unless arity == g.arity
  proc{ |*a| self[*g[*a] ] }
 end

end

but from the very first ...
as you can see, we extend the build-in class Proc, since all of ruby's classes are open for that kind of extension.

Procs

Procs are - simply said - some block of code, that have been bound to a set of local variables (see the pickaxe book). This bunch of code is captured and represented by a Proc object that can be called at any time after it's definition:
double = Proc.new {|x| x * 2 }

double.call( 5 ) # => 10
alternatively you can use the so called lambda operator, which will instantiate a given code block as a Proc object:
half_of = lambda {|x| x / 2 }

half_of.call( 8 ) # => 4
and - not enough - another way to define a proc is using Kernel#proc:
square = proc {|x|x*x}

square( 4 ) # => 16

i spy with my little eye something beginning with ...


as seen, Procs can take an arbitrary number of arguments ('x' as the only argument in the above examples), delivering a return value which is by default evaluated as the last expression inside that code block - so a Proc looks like an anonymous method, which can be assigned to a variable.
But more than a method, a Proc is able to refer to the set of local variables bound to the context it was defined within (even if that context isn't visible anymore to the callers environment):
def salutation( male ,female )
  female_names = [:Alicia, :Samantha, :Kathy]

  male_names = [:John,:Ben,:Harvey]

   lambda do |name|
    return female + name #...
     if female_names.include? name.intern

     return male + name #...
    if male_names.include? name.intern

     "Dear " + name
   end
end

salutation_friends = salutation("Yo ","Hi ")
salution_pen_pals = salutation("Howdy ","Hello ")

puts salutation_friends.call("Ben")
# => 'Yo Ben'

puts salution_pen_pals.call("Alicia")
# => 'Hello Alicia'

puts salution_pen_pals.call("Dave")
# => 'Dear Dave'

first of all, the two arrays defining the known male and female names are (only) visible inside the scope of method salutation(). but even after the method execution ends, the created Proc refers to that arrays when called afterwards. this is also true for the given arguments with which the method salutation() gets called. even if we invoke the method more than once with different arguments, the created Proc 'remembers' those different values!
furthermore, you surely have noticed that we used the do...end syntax for defining the code block. this is a very suitable way when having a code block with more than one line.

it's not a bird

we can use another notation in order to invoke a Proc object. up to now, we called Proc's instance method call() for invocation. as a shortcut you can always use []. when i saw this notation the first time, i was bit of confused - this seems a little odd since it may remind you of the notion of an array. of course ruby lets you override the [] operator in any class you want to, and so it is for class Proc as a synonym for Proc#call.
puts salutation_friends["Kathy"]
# => 'Hi Kathy'

whatever way you'll choose to invoke a Proc object, you may want to know the correct number of arguments a Proc object can handle. in this case you can use the instance method Proc#arity on the object. it will betray the number of arguments, which will be processed by the Proc's instance.
in case you have a Proc object that accepts an argument array (we will have a deeper look at this kind of argument in the next section) Proc#arity will return a negative number - begining with -1 for only having an argument array, decreasing the number with every additional mentioned single argument:
lambda {|arg1|}.arity
# => 1

lambda {|arg1,arg2,arg3|}.arity
# => 3

lambda {|*args|}.arity
# => -1

lambda {|arg1,*args|}.arity
# => -2

lambda {|arg1,arg2,arg3,arg4,*args|}.arity
# => -5
open-hearted

Procs are very communicative! as mentioned before, you can pass an arbitrary number of arguments to a Proc object. it's also possible to use the array notation like in method definitions in order to access a dynamic number of arguments:
pick = lambda {|pos,*cards| cards[pos-1] #...
 if pos > 0 and pos < cards.size}

pick[3, 'diamonds', 'hearts', 'spades', 'clubs']
# => 'spades'

you have to be careful when delegating an argument array to a Proc object, for example inside a method. if you forget to use the asterisk again when calling the Proc with the given argument array, the Proc will only receive a single, 'joined' argument:
def start_play(pick,*cards)
  # here we delegate the argument array correctly
   pick[1, *cards]
end

def next_move( pick, *cards )
  # oops, we missed the asterisk !
   pick[2, cards]
end

first_card=start_play #...
 (pick,'diamonds','hearts','spades','clubs')
# => 'diamonds'


second_card=next_move #...
 (pick,'diamonds','hearts','spades','clubs' )
# => nil

the same is true for return value(s). since you are able to return more than one value in ruby, you could return an array of return values:
words_with_length = lambda do|c,*words|
  hits = []
  words.each do |word|
    hits << word if word.size == c
  end
  hits
end

words_with_length #...
  [4,"Sue","Mike","Walter","Tara","Beth","David" ]
# => ['Mike', 'Tara', 'Beth']

again, if you want to pass an result array of a Proc as an argument to another Proc which can handle an argument array (sounds as if we could nest calls of Proc objects, eh?), again you have to watch out not to forget the asterisk! otherwise your result array will be also handed over as a single, joined argument:
line_print = lambda do |*words|
  words.each_index do |i|
    puts "#{i+1} #{words[i]}"
  end
end

# ok, asterisk on board !
line_print[ *words_with_length #...
 [4,"Sue","Mike","Walter","Tara","Beth","David"]]

1 Mike
2 Tara
3 Beth

# ouch, missed again:
line_print[ words_with_length #...
 [4,"Sue","Mike","Walter","Tara","Beth","David"]]

1 MikeTaraBeth

inside out

now we have enough information to get back to our 'darling from page 1' ... here's the code again:

class Proc
 def *(g)
  raise ArgumentError, "arity count mismatch" #...
  unless arity == g.arity
  proc{ |*a| self[*g[*a] ] }
 end

end

now it's easy to understand what's happening inside the method Proc#*. we will go through the code from inside out:
first of all, we can see, that the method will create and return another Proc object (using Kernel#proc for instaniating the Proc object), which will accept a dynamic range of arguments.

this argument array is passed to the proc named g. it's the argument of Proc#*(as the newly created and returned Proc object is able to refer to all variables of its defining context, it of course can refer to Prog g when it will be called).

we know furthermore, that we have to keep the asterisk when passing the argument array to a Proc instance, thus also when passing it to Proc g, using the []-operator notation ('g[*a]').

So what happens next? at the end of Proc g's execution it may will return one return value or even a return value array. since we want to be generic, we allow an arbitrary number of return values (which subsumes all Procs which will return one or no return value at all).

the call of Proc g is nested inside the call of the current Proc object (which is represented by 'self'). so the argument of self Proc is the return of Proc g (never fear, we've already seen nested calls before and this is pretty the same thing).
since Proc g returns at least an arbitrary number of arguments which shall be passed as an argument array to the self Proc as the receiver, again we have to keep the asterisk ('self[*g[*a]').

thats all of the relevant stuff. before creating this new Proc, which is nesting the calls of self Proc and the Proc given as the argument, there is a check, if the number of arguments of these two Procs are the same. otherwise an exception is raised. from my point of view this check acts only as a kind of makeshift, since we should check if the number of return values of the inner Proc meets the number of arguments the outer Proc is willing to accept.

we now could use our new notation of composing two procs:
square = lambda {|x| x*x}

cube_length = lambda{|volume|volume**(1.0/3)}

cube_area = square * cube_length

cube_area[100]
# => 21.5443469003188

this is a pretty small example, but it illustrates the idea very well.
composing Proc objects can now be done in a simple, concise way. since ruby doesn't demand dot notation for method calls (the asterisk between the two Procs is automatically assumed to be a method of the object that stands on the left side of the method's identifier) we have gained a nice and readable way of Proc composition.

but beside that, we may have got a little deeper insight of how Procs do their job ... ;o)



Posted by mario.gleichmann at 02:30:26 | Permanent Link | Comments (4) |

Sunday, 10. December 2006

ruby metaprogramming I

just played a little with some basic groundwork of ruby's potentials upon metaprogramming. metaprogramming still is and even will become more important in regard to the increasing relevance due to domain specific languages (dsl). in the context of modeling such a dsl and expressing domain specific concepts within it, metaprogramming is a powerful and very flexible option, since it will provide the full power of ruby's features when it comes to modeling domain concepts.

with the rise of java 6 and especially the support for scripting languages (jsr 223 - scripting for the java platform) such potentials could become strategic, since half typed languages like java are quite inflexible for extensions due to domain specific needs. scripting languages like ruby could play an important role in the next future, since it will be very easy to interoperate. given this, one could take the power of both sides java and ruby, when it comes to the implementation of applications. one could apply the right instrument to the approriate parts of an application in order to benefit from the strength of each particular language. for example, web application layer could be done using rails, but java provides its full power under the hood when asking for security, transactionional services, distribution or integration of legacy systems. the core business logic (especially where the domain drives complexity) could be expressed using a domain specific language, again falling back to ruby's above mentioned potentials ...

so much for the motivation ... now to the action ...

come in - we're open, too

one basic feature of ruby's possibilities due to metaprogramming is its facility of extending almost everything, even 'build in' classes. so its very easy to enrich a given class with new features.

if we would ask a number if it's an odd one, we would receive a reaction like the following:


> 23.odd?
NoMethodError: undefined method `odd?' for 23:Fixnum

this is normal behaviour since class Fixnum doesn't provide such a method.
but thanks to the openness of classes, we can enhance Fixnum at any time and pay for a new method:


class Fixnum
   def odd?
     self % 2 == 1
  end
end

if we now ask the number a second time, the sun will shine again ...


> 23.odd?
=> true



enhancing class features

what about enhancing the features of class itself?
you may know about 'attr_reader' or 'attr_writer' in order to define instance properties without explicitly defining 'getters' and 'setters' (sorry, i'm originally a java guy).


class Person
  attr_reader :firstname, :lastname, :birthday
  attr_writer :firstname, :lastname, :birthday
end


we have to do so - declaring attr_reader for offering 'getter' and declaring attr_writer for offering 'setter' functionality - because there's no feature of declaring both 'setter' and 'getter' in one go.
now, if we would consider it nice to have such a feature - let's enhance ...

since everything is an object in Ruby world, also Class is nothing more than a specific class that - among others - inherits from Object, you can of course also enhance the definition of class and let all class definitions (which 'uses' Class) benefit from that enhancements:


class Class
  def attr_rw( *attrib_names )
    attrib_names.each do |name|
      attr_reader name
      attr_writer name
    end
 end
end


as you can see, Class now owns a new method attr_rw, which delegates the passed property names to both attr_reader and attr_writer, means that both 'getter' and 'setter' functionality will be assigned.

we now could use this new feature as it would be a normal 'keyword' of the language, like attr_reader or attr_writer:


class Person
  attr_rw :firstname, :lastname, :birthday
end

admitted, this is a very simple example, but it shows the power of enhancing the 'core' language with new 'concepts' quite well.
it's a first step towards the way of metaprogramming ...

 

Posted by mario.gleichmann at 02:09:13 | Permanent Link | Comments (7) |