Archive

Archive for the ‘Polyglot’ Category

GOF Series: Episode #4 [The Builder Pattern] - In IronRuby

November 5th, 2008 Simon Segal 3 comments

So first up let me say that the balance of this series of posts on patterns will be presented using either C# or IronRuby as languages to express the GOF patterns. Why IronRuby you ask? I have taken to learning IronRuby and Silverlight as deeply as possible this year and decided to spice things up for myself by incorporating it in this series of posts. Never fear I will continue to demonstrate most of the remaining patterns in C# but will from time to time present the patterns in both languages. For now however it’s the Builder Pattern exclusively in IronRuby for the dynamic language enthusiasts.

IronRuby is a dynamically typed, object oriented language and runs in the Dynamic Language Runtime. We will demonstrate the builder pattern using IronRuby, Windows Forms and the Ruby In Steel plugin for Visual Studio.Net 2008.

The goal of the Builder Pattern is to separate or abstract away the construction of an object and to allow the same / common construction process to create the object regardless of its representation. The different representations of the object being constructed are created by concrete builders, specifically designed to create one and only one representation of the product class.

The players in the story:

  • The Director

    • Responsible for constructing the Product object via an interface (mixin in the case of this example using IronRuby) implemented by a concrete builder.
  • The Builder

    • Provides the interface (object in this case) that creates the Product(s) constituent parts and is implemented (included as a mixin with IronRuby) by concrete builders.
  • The Concrete Builder

    • Builds the constituent parts of the Product object.
  • The Product

    • The object whose parts are created by the concrete builder.

BuilderPattern

In C# or other statically typed languages such as java, the builder pattern relies on an abstract class design and inheritance. In IronRuby there is no concept of an interface therefore a different approach is required. We can use a mixin to provide the common behavioural aspects and use arguments to diverge the different concrete builders. The construction of the ‘Product’ is abstracted from the ‘Director’ by the ‘Builder’ and it’s Concrete implementations. To obtain different representations of the Product object new concrete builder objects are created. The Builder Pattern creates it’s Product object in parts via the Director and Builders abstract signatures, however an alternate approach with IronRuby is to substitute the abstract class for a mixin.

#Product
class FootballTeam

    def team_id?()
        self.hash
    end

    def team_type_name?()
        @team_type_name
    end

    def team_properties?()
        @team_properties
    end

    def initialize(name)
        @team_type_name = name
        @team_properties = Hash.new(“Staff Role does not exist!”)
    end

end

#Builder
module FootballTeamBuilder

    attr_reader :name
    attr_writer :name

    def footy_team?()
        @footy_team
    end

    def build_init()
        @footy_team = FootballTeam.new(name)
    end

    def build_players(number_of_players)
        @footy_team.team_properties?["Players"] = number_of_players
    end

    def build_ball_shape(shape_of_ball)
        @footy_team.team_properties?["ballshape"] = shape_of_ball
    end

    def build_games_per_season(number_of_games)
        @footy_team.team_properties?["games"] = number_of_games
    end

    def print_team_details()

        attributes =  “****************************” +
            “******************************\r\n”

        attributes += “Created a #{name} team with the “ +
            “following attributes :\r\n”

        @footy_team.team_properties?.each { |k,v|
            attributes += k.to_s + ” “ + v.to_s + “\r\n” }

        attributes += “\n***************************” +
            “*******************************\n”

        return attributes
    end

end

#Concrete Builder”
class AustralianRulesFootballTeamBuilder 

    include FootballTeamBuilder

    def build_all()
        self.name = “Aussie Rules”
        build_init()
        build_ball_shape(“Oval”)
        build_games_per_season(22)
        build_players(18)
    end

end

#Concrete Builder
class RugbyLeagueFootballTeamBuilder

    include FootballTeamBuilder

   def build_all()
        self.name = “Rugby League”
        build_init()
        build_ball_shape(“Oval”)
        build_games_per_season(24)
        build_players(13)
    end

end

#Concrete Builder
class SoccerFootballTeamBuilder

    include FootballTeamBuilder

    def build_all()
        self.name = “Soccer”
        build_init()
        build_ball_shape(“Round”)
        build_games_per_season(44)
        build_players(11)
    end

end

#Director Class
class GoverningBody

    def build_football_team(football_team_builder)
        unless football_team_builder.is_a?(FootballTeamBuilder)
            fail NoNewMethodError.new(“Cannot build with arguments that are “ +
                “not FootballTeamBuilder class objects”)
        end
        football_team_builder.build_all
    end

end
 
Here’s our form and its form load event method.
 
def Form1_Load(sender, e)

      #new up a Director
      f = GoverningBody.new

      #new up a concrete builder
      soccer_builder = SoccerFootballTeamBuilder.new

      #go again a second time with another builder
      aussie_rules_builder = AustralianRulesFootballTeamBuilder.new

      #go again a second time with another builder
      rugby_league_builder = RugbyLeagueFootballTeamBuilder.new

      #pass the bulders build to the Director
      f.build_football_team(soccer_builder)
      f.build_football_team(aussie_rules_builder)
      f.build_football_team(rugby_league_builder)

      #store the teams and details in arrays
      @team1 = [soccer_builder.footy_team?.team_type_name?,
        soccer_builder.print_team_details]
      @team2 = [aussie_rules_builder.footy_team?.team_type_name?,
        aussie_rules_builder.print_team_details]
      @team3 = [rugby_league_builder.footy_team?.team_type_name?,
        rugby_league_builder.print_team_details]

      self.listBox1.Items.Add(@team1[0])
      self.listBox1.Items.Add(@team2[0])
      self.listBox1.Items.Add(@team3[0])

end
ironruby_builder_ui
ironruby_builder_ide Used in concert with a Windows::Forms application (with some help from Ruby In Steel) we can build the following user interface to demonstrate our Builder(s) in action. The entire code can be found here and includes all the code and presentations from previous episodes in the series. Next in the series is the last of the creational patterns, the Prototype pattern.

Share/Save/Bookmark

Preparing for IronRuby

October 7th, 2008 Simon Segal No comments

I decided to share my experiences on the path to IronRuby so far and perhaps it might be useful to others who wish to travel that road.

Not so long ago I posted about choices in front of me regarding learning a new language. After having programmed in C# for some 7 or so years I wasn’t going to choose another statically typed language, I wanted to add a dynamic language to my arsenal and with the DLR on it’s way and a key interest and stake in the Silverlight, the choice as obvious.

After having decided to dedicate the time and effort to IronRuby, the next question was how to address the learning. Clearly picking up IronRuby as the first pit stop was going to come with some difficulties borne out of the fact that the documentation isn’t great yet and the toolset way of being close. Based on this, I decided that learning Ruby first was the best way to progress this goal for two main reasons, one it allowed me to learn in the comfort of an IDE (NetBeans) to write ‘do as you learn‘ code and also gave me a perspective on IronRuby that is not indifferent to its genealogy.

So after downloading NetBeans (Ruby Edition) and installing Ruby 1.8.6, I got my hands on the excellent free online book by Jeremy McAnally, the title of which is “Mr Neighbourly’s Humble Little Ruby Book“. This book is a nice little quick starter to get you comfortable with the absolute basics of Ruby, but needs to be followed by something with a bit more industrial strength such as Matz very own offering The Ruby Programming Language.

DLR PadOnce having navigated this far, I decided that it was time to pull down the IronRuby bits and start to have a play. A while back now, Hanselman and Gu both posted some early pieces on getting started with IronRuby. Most people seem intent on making XAML based applications the focus of their IronRuby attention, which in turn lead me to DLR Pad (see the image above) which provides the ability to interactively script IronRuby (and IronPython) against a statically set window that contains a XAML UI layout (interesting). From there I found my way to Ivan Porto Carerro’s blog and book on IronRuby. Ivan’s book is not yet released but is available as early access, so I decided to avail myself of it.

And if your wondering what code looks like (see below) for something that you might have been routinely doing (as I was), it doesn’t take long to knock something (trivial in this case) together to begin to get the picture, in the case of having gone down the path I described above.

require ‘mscorlib’
require ‘System.Windows.Forms,
  Version=2.0.0.0, Culture=neutral,
  PublicKeyToken=b77a5c561934e089′

begin

    #alias the forms namespace
    Windows = System::Windows::Forms
    #new up a form & set it’s text
    first_ruby_window = Windows::Form.new
    first_ruby_window.Text = “Simons first Ruby Form”
    #new up a button
    first_ruby_button = Windows::Button.new
    #subscribe to the buttons click event
    first_ruby_button.click {|sender, args| first_ruby_button.Text =
                                    “I got clicked!”}
    #add the button to the form
    first_ruby_window.Controls.Add(first_ruby_button)
    #show my new form
    first_ruby_window.ShowDialog()

end

And we get the following:

first_ruby_form

So that’s my story (to date) and perhaps it offers some help in getting you underway with your IronRuby / DLR journey.

Share/Save/Bookmark

learning Ruby, IronRuby, the DLR, F# and DSL’s - so much to consider.

September 5th, 2008 Simon Segal 1 comment

ruby I just cant seem to shake Ruby off. Often something comes up in my day to day job that pushes me get serious about Ruby and for as long I have the idea of the Polyglot programmer in the back of my mind, I feel compelled to find out more, even if it’s in microscopic increments. A while back I installed Ruby on my development laptop and played with the interactive console for a while and then predictably got distracted and didn’t follow up for months, until today when I  downloaded NetBeans (Ruby version only) and made a decision, that to understand Domain Languages better I wanted to learn more about a language that would help in that understanding. Ruby is well thought of with respect to being a useful language to ms rubydevelop internal DSL’s and given the other sentiment in this post, I thought it was as good a choice as any. I have been a C# developer since beta of the 1.0 Framework and now that IronRuby and DLR are close at hand, I feel compelled to let my interest in DSL’s, the DLR and learning a dynamic language begin to engulf me to the point that I have been stung into action. So with this in mind I am setting down the path to learn Ruby and hope that this provides a great springboard into taking up IronRuby. Of course the benefit of going deep into another development language and platform I believe will lead to a far richer appreciation of the platform I am currently so deeply invested in.

Last Minute Update:

After re-listening to the HanselMinutes podcast with Robert Pickering on F#, it would appear that F# is a potentially useful language for creating internal DSL’s. I have been thrown a little as I must confess this threw things into debate for a short moment. The argument that kept me down the Ruby path was the relationship that IronRuby has with the DLR and the upside that brings to the learning experience. FsharpYellow Last minute problem solved. Wait hold the press. VbX or Visual Basic 10 is on its way and it too will be a dynamic language. Dilemma. Given that I am almost  equally conversant in VB as C# (I prefer C# by choice), perhaps I should concentrate on F# and let my strong understanding of VB languages to carry me through the transition to VB10 which gives me the DLR leverage? Again I decide to take the Ruby path also because its not a Microsoft Language per se and I think the exposure to Ruby in general will do me good from a platform perspective. I would also like to use Ruby in exploring RESTful Web Services. So I have downloaded NetBeans and installed Ruby 1.8.6 and here I go.

Share/Save/Bookmark

Categories: DLR, DSL, F#, IronRuby, Polyglot, Ruby Tags: , , , ,
Creative Commons Attribution-ShareAlike 2.5 Australia
Creative Commons Attribution-ShareAlike 2.5 Australia