Ruby, Rails, Web2.0 http://www.rubyrailways.com Experiences with Ruby and Rails, Web2.0 and other development technologies Mon, 05 May 2008 18:59:31 +0000 http://wordpress.org/?v=2.0.2 en acts_as_state_machine for Dummies, part I http://www.rubyrailways.com/acts_as_state_machine-for-dummies-part-i/ http://www.rubyrailways.com/acts_as_state_machine-for-dummies-part-i/#comments Mon, 05 May 2008 12:18:42 +0000 peter Ruby TutorialRailsRubyTutorial http://www.rubyrailways.com/acts_as_state_machine-for-dummies-part-i/ I recently applied this great plugin a few times to tackle different tasks and would like to share with you the joys of thinking in state machines!

Disclaimer: This installment is ‘just’ an intro to the topic (a teaser if you like), it doesn’t contain actual instructions or code on how to use actsasstate_machine - that comes in part II. Though the original intent was to write up a small tutorial with some example code, I started with an intro and the article grew so long that I decided to split it up - so stay tuned for part deux!

State what…?!?

A finite state machine (FSM for short) a.k.a. finite state automaton (FSA) is a 5-tuple (Σ,S,s0,δ,F)… OK, just kidding. I doubt too much people are interested in the rigorous definition of the FSM (for the rest, here it is), so let’s see a more down-to earth description.

According to wikipedia, Finite state machine is “a model of behavior composed of a finite number of states, transitions between those states, and actions“. Somewhat better than those gammas and sigmas and stuff but if you are not the abstract thinker type, it might take some time to wrap your brain around it. I believe a good example can help here!

Everybody knows and loves regular expressions - but probably it’s not that wide known fact that regular expression matching can be solved with an FSM (and in fact, a lot of implementations are using some kind of FSM on steroids). So let’s see a simple example. Suppose we would like to match a string against the following, simple regexp:

ab+(a|c)b*

First we have to construct the FSM, which will be fed with the string we would like to match. An FSM for the above regular expression might look like this:

fsm_correct.png

String matching against this FSM is basically answering the question ’starting from the initial state, can we reach the finish after feeding the FSM the whole string?’. Pretty easy - the only thing we have to define is ‘feeding’.

So let’s take the string ‘abbbcbbb’ as an example and feed the FSM! The process looks like this:

  1. we are in q0, the initial state (where the ’start’ label is). Starting to consume the string
  2. we receive the first character, it’s an ‘a‘. We have an ‘a‘ arrow to state q1, so we make a transition there
  3. we receive the next character, ‘b‘. We have two b-arrows: to q1 and q2. We choose to go to q1 (in fact, staying in q1) - remember, the question is whether we _can_ reach the finish, not whether all roads lead to the finish - so the choice is ours!
  4. identical to the above
  5. after the two above steps, we are still in q1. We still get a ‘b‘ but this time we decide to move to q2.
  6. we are in q2 and the input is ‘c‘. We have no analysis-paralysis here since the only thing we can do is to move to q4 - so let’s do that!
  7. Whoa! We reached the finish line! (q4 is one of the terminal states). However, we didn’t consume the whole string yet, so we can’t yet tell whether the regexp matches or not.
  8. So we eat the rest of the string (the ‘how’ is left as an exercise to the reader) and return ‘match!’

Let’s see a very simple non-matching example on the string ‘abac’

  1. in q0
  2. got an ‘a‘, move to q1
  3. in q1, got a ‘b‘, move to q2
  4. in q2, got an ‘a‘, move to q3 - we reached the finish, but still have a character to consume
  5. in q3, got a ‘c‘… oops. We have no ‘c’ arrow from q3 so we are stuck. return ‘no match!’

Of course the real-life scenarios are much more complicated than the above one and sometimes FSMs are not enough (for example to my knowledge it’s not possible to tell about a number whether it is prime or not with a vanilla FSM - but a regexp doing just that has been floating around some time ago) but to illustrate the concept this example served fine.

This is cool and all but why should I care?!?

Well, yeah, you are obviously not going to model an FSM the next time you would like to match a regexp - that would be wheel-reinvention at it’s finest. However there are some practical scenarios where an FSM can come handy:

  • sometimes the logic flow is just too complicated to model - an if-forrest is rarely a good solution (on the flip side, don’t model an if-else with an FSM :-) )
  • encapsulate complex logic flow into a pattern and not clutter your code with it.
  • you are in a stateless world - for example HTTP
  • asynchronous and/or distributed processing where you explicitly need to maintain your state and act upon it

Some real life examples of FSM usage in the Ruby/Rails world are why the lucky stiff’s Hpricot (using Ragel) or Rick Olson’s restful authentication plugin (using actsasstate_machine)

The Next Episode

In the next installment I’d like to focus on the practical usage of the actsasstate_machine plugin - I’ll attempt to create an asynchronous messaging system in a Rails app using it.

tags: ]]>
http://www.rubyrailways.com/acts_as_state_machine-for-dummies-part-i/feed/
Random Links from the Web, 26-04-2008 http://www.rubyrailways.com/random-links-from-the-web-26-04-2008/ http://www.rubyrailways.com/random-links-from-the-web-26-04-2008/#comments Sat, 26 Apr 2008 21:13:22 +0000 peter Uncategorized http://www.rubyrailways.com/random-links-from-the-web-26-04-2008/
  • Easy git-svn for Rails - I really can’t imagine how could it be easier to move from svn to git. Really no more excuses!
  • Writing Your Own Front Controller for Rails - forget about routes.rb. A less drastic solution is the Catch-all Route.
  • Sidebars and Other Dynamic Content - Dynamically filling elements of your layouts. (Additional stuff to the railscast “5 View Tips”).
  • tags:]]>
    http://www.rubyrailways.com/random-links-from-the-web-26-04-2008/feed/
    Cool JS Shadow Library http://www.rubyrailways.com/cool-js-shadow-library/ http://www.rubyrailways.com/cool-js-shadow-library/#comments Fri, 25 Apr 2008 20:54:45 +0000 peter Web2.0 JavaScriptJavaScriptWeb2.0 http://www.rubyrailways.com/cool-js-shadow-library/ light_and_shadow.png Light & Shadow is a ProtoType-based library for creating great looking drop shadows easily. Check out the HTML I used to generate the example image and see it yourself that it’s not rocket science!

    All you have to do is to set up a light source with a few parameters (distance, intensity, size etc.) and add the class ’shadowThrowing’ to your elements which should… well, throw shadows :-) . I won’t go into details here, you can find the explanation and other details on the Light & Shadow project page.

    (Found via Gedankenkonserve - thanks Bernhard ;-) )

    tags: ]]>
    http://www.rubyrailways.com/cool-js-shadow-library/feed/
    Today Midnight http://www.rubyrailways.com/today-midnight/ http://www.rubyrailways.com/today-midnight/#comments Thu, 24 Apr 2008 13:10:46 +0000 peter RubyRuby http://www.rubyrailways.com/today-midnight/ I have been always uncertain about the exact expression denoting today midnight (or any day midnight, for that matter). Is 00:00 on e.g. April 24th the midnight between 23rd and 24th or 24th and 25th? If I want something to happen at today midnight, is that today’s date at 00:00? (for the impatient: no, it isn’t :-) ).

    Chronic to the rescue! (If you don’t know chronic, be sure to check it out - it’s a great natural language date/time parser). All I had to do is:

    1. >> Chronic.parse(‘today midnight’)
    2. => Fri Apr 25 00:00:00 +0200 2008

    so actually it turns out it’s tomorrow’s date at 00:00.

    I couldn’t find time zone support though (I am not saying it’s not there, just that I couldn’t find it by looking at the API) - so what if I want to meet someone in Madrid today midnight? Why, I install the tzinfo gem and ask Ruby!

    1. >> TzinfoTimezone["Madrid"].utc_to_local(Chronic.parse(‘today midnight’).getutc)
    2. => Fri Apr 25 00:00:00 UTC 2008
    tags:]]>
    http://www.rubyrailways.com/today-midnight/feed/
    Random Links from the Web, 22-04-2008 (AI edition) http://www.rubyrailways.com/random-links-from-the-web-22-04-2008-ai-edition/ http://www.rubyrailways.com/random-links-from-the-web-22-04-2008-ai-edition/#comments Tue, 22 Apr 2008 08:57:07 +0000 peter Ruby NewsNewsRuby http://www.rubyrailways.com/random-links-from-the-web-22-04-2008-ai-edition/
  • AI Ruby plugins (via rubyflow.com) - list of AI related libraries for Ruby. Parsing, Machine Learning, Semantic stuff…
  • Programming Collective Intelligence Python to Ruby translation - I guess a lot of people here read Programming Collective Intelligence from Toby Segaran. I can only recommend it - it’s a great book, and now even better with Ruby source code ;-)
  • tags: ]]>
    http://www.rubyrailways.com/random-links-from-the-web-22-04-2008-ai-edition/feed/
    Random Links from the Web, 21-04-2008 http://www.rubyrailways.com/random-links-from-the-web-21-04-2008/ http://www.rubyrailways.com/random-links-from-the-web-21-04-2008/#comments Mon, 21 Apr 2008 15:10:44 +0000 peter Uncategorized Ruby Rails NewsNewsRailsRuby http://www.rubyrailways.com/random-links-from-the-web-21-04-2008/
  • Git and Ruby Tutorials - a great collection from rubyinside.com, also the comments contain a few good pointers.
  • acts_as_dropdown - acts_as_dropdown allows any ActiveRecord class to be easily used as the contents of a HTML select tag.
  • Handling JavaScript Events on Multiple Elements - proper JS/Prototype event handling!
  • tranexp - Dr. Nic in action again. This time it’s a dead simple translator gem.
  • tags: ]]>
    http://www.rubyrailways.com/random-links-from-the-web-21-04-2008/feed/
    Live Validation - Easy Client-side Javascript Validation http://www.rubyrailways.com/live-validation-easy-client-side-javascript-validation/ http://www.rubyrailways.com/live-validation-easy-client-side-javascript-validation/#comments Tue, 15 Apr 2008 14:37:09 +0000 peter Rails JavaScriptJavaScriptRails http://www.rubyrailways.com/live-validation-easy-client-side-javascript-validation/ live_validation.pngUpdate: Sergio, the author of the livevalidation rails plugin updated the plugin so you can disregard the finale of the article (validatesconfirmationof is working, as well as the newest version of livevalidation, 1.3 is used in the plugin - so no additional tweaking is needed, install and validate away ;-) )

    Surely I am not the only one who was a ‘bit nervous’ (that was a mild euphemism) when his carefully entered data disappeared after submitting a form to the server. Nowadays web applications are doing better than that - valid data is saved and only the problematic fields are pointed out.

    Of course even that feels so 1990’s now. A contemporary (ehm… web 2.0?) web application is expected to validate the form on the client side already (WARNING! That doesn’t mean at all you shouldn’t validate on the server side though - client side validation is for the good guys but you should still look out for the script kiddies et al), pointing out the errors on the fly so there is no need to come back and change/edit those fields after submitting a form.

    My library of choice is livevalidation, which has a Rails companion too - if you are using Rails form helpers and standard validation on your models, you don’t have to touch anything just install livevalidation (=drop it to your javascripts folder, it’s a single .js file). w00t!

    The only major shortcoming (from my POV) of the Rails plugin is that validatesconfirmationof is not implemented. However, it’s easy to add it via standard javascript:

    <input id="user_password" name="user[password]" size="30" type="password" />
    <input id="user_password_confirmation" name="user[password_confirmation]" size="30"> 
    <script type="text/javascript">
    var validate = new LiveValidation('user_password_confirmation');
    validate.add( Validate.Confirmation, { match: 'user_password' } );
    </script>
    

    That’s it!

    One more note: the Rails plugin contains version 1.2 but there is a newer version, 1.3 so be sure to replace it.

    tags: ]]>
    http://www.rubyrailways.com/live-validation-easy-client-side-javascript-validation/feed/
    Caffeine and Insomnia - Don’t Let Your Mac Fall Asleep http://www.rubyrailways.com/caffeine-and-insomnia-dont-let-your-mac-fall-asleep/ http://www.rubyrailways.com/caffeine-and-insomnia-dont-let-your-mac-fall-asleep/#comments Sun, 13 Apr 2008 14:56:00 +0000 peter MacMac http://www.rubyrailways.com/caffeine-and-insomnia-dont-let-your-mac-fall-asleep/ caffeine.png Long-time Mac users probably have different solutions for this problem, but as a newbie, the screen going dim after a certain period of time - without an intuitive way to switch this off - drove me crazy! I wanted to enjoy my slideshow, video, presentation, reading something etc. and suddenly it all went dark. Arggghhh.

    So I was delighted when I found Caffeine, a super-light program sitting in your menu bar that prevents your Mac from going to sleep/starting screen savers.

    Note that Caffeine doesn’t help if you close the lid - if you want your Mac to stay awake in this case, InsomniaX is your thing - it disables the sleep when closing the lid so you can listen to music/control your Mac with the remote etc.

    tags:]]>
    http://www.rubyrailways.com/caffeine-and-insomnia-dont-let-your-mac-fall-asleep/feed/
    Random Links from the Web, 10-04-2008 http://www.rubyrailways.com/random-links-from-the-web-10-04-2008/ http://www.rubyrailways.com/random-links-from-the-web-10-04-2008/#comments Thu, 10 Apr 2008 13:44:39 +0000 peter Uncategorized http://www.rubyrailways.com/random-links-from-the-web-10-04-2008/
  • RubyFlow - Peter Cooper (of RubyInside fame) created “RubyInside’s sister site” - RubyFlow. Hope it takes off!
  • Thinking Sphinx Reborn - I thought a phoenix is the creature with the reborn ability - though that doesn’t mean a sphinx can’t do that! btw. “Sphinx is a very fast search engine that indexes data and provides flexible ways of searching it.”
  • Rails vs Merb - “The conclusion is simple, I recommended that my client go with Merb”.
  • RubyAMP - powerful looking Ruby TextMate bundle.
  • tags:]]>
    http://www.rubyrailways.com/random-links-from-the-web-10-04-2008/feed/
    Compiling Firefox 3 beta 5 on OS X (with JSSH support) http://www.rubyrailways.com/compiling-firefox-3-beta-5-on-os-x-with-jssh-support/ http://www.rubyrailways.com/compiling-firefox-3-beta-5-on-os-x-with-jssh-support/#comments Tue, 08 Apr 2008 17:55:43 +0000 peter Uncategorized Mac FireWatirFireWatirMacMozilla/FirefoxNewsRuby http://www.rubyrailways.com/compiling-firefox-3-beta-5-on-os-x-with-jssh-support/ Since I bought my Mac, Safari has been my primary browser of choice. I have been using Firefox sporadically too - you can’t do serious web development without FireBug! Safari is light, zippy and renders wonderfully looking OS X look’n'feel pages - however with the arrival of Firefox 3 I am really pondering to ditch it in favor of FF (still no OS X look in there, tho’ ;-) ). Firefox 3 beta 5 is just phenomenal - fast, powerful, and it has all the stuff I am missing from Safari (FireBug, del.icio.us toolbar, DOM Inspector, ton of other extensions) so I am really thinking that I will remain a Safari user on my iPhone only.

    However, FF3 is missing some functionality I am depending on - most notably jssh support - DOM inspector was removed too, but can be installed as an add-on, and since beta 4 FireBug is working, so no major hurdles there. However, jssh, as usually was a harder nut to crack.

    Fortunately Angrez, FireWatir’s author pointed me to the right direction - which was in this case compiling Firefox 3 with jssh support! Here’s how:

    Sit back, enjoy your coffee and in a few minutes you’ll have your own, new hot FF build with jssh support!

    By the way, FireWatir 1.1 hit the streets just today! Grab it and let the testing commence!

    tags: ]]>
    http://www.rubyrailways.com/compiling-firefox-3-beta-5-on-os-x-with-jssh-support/feed/