Sashimi: Getting Started Tutorial 0

Posted by luca
on Monday, June 30

Here a getting started tutorial for Sashimi

. Sashimi getting started tutorial

Released Sashimi 0.1.6 0

Posted by luca
on Monday, June 23

I just released a new version of Sashimi, with tiny fixes and a new home! In fact the project is also hosted on RubyForge, now you can install the gem with:

$ (sudo) gem install sashimi
or with:
$ (sudo) gem install jodosha-sashimi --source=http://gems.github.com

If you wish, you can visit the project pages on GitHub and on RubyForge.

UPDATE The release 0.1.6 is broken, you are strongly encouraged to update your gem with the newest 0.1.7.

Ruby: Class Methods Proxy 2

Posted by luca
on Thursday, May 29

Did you ever used class methods inside your instance methods? If yes, you probably noticed how frustrating can be to use the self.class.my_class_method syntax. A solution could be to create a private method which encapsulates the class one.

class Repository
  def self.path
    @@path
  end
  
  def print_path
    puts path
  end
  
  private
    def path
      self.class.path
    end
end
In the above example, #print_path can print the @@code value, without worrying about it's a class value, because we have wrapped it.

When I developed Sashimi I've widely used this technique, with a bad impact on the code duplication, and in order to DRY-up my code I extended the Ruby's Class class in this way:

class Class
  def class_method_proxy(*method_names)
    method_names.each do |m|
      self.class_eval %{
        # Proxy method for <tt>#{self.class.name}##{m}</tt>
        def #{m}(*args)
          self.class.#{m}(*args)
        end
        private :#{m}
      }, __FILE__, __LINE__
    end
  end
end

This approach allow us to annotate our classes, choosing which class methods should be available as private methods.
Now, our example class should look like the following:

class Repository
  def self.path
    @@path
  end
  class_method_proxy :path

  def print_path
    puts path
  end
end

Of course you can pass multiple symbols to proxy many methods at the same time.

class_method_proxy :path, :another_path, :a_third_one

Sashimi: Just Received A Tasteful Update 0

Posted by luca
on Tuesday, May 20

Yesterday I announced Sashimi and now it's already time of tasteful updates.

Changes

First, thanks to all the people that appreciated my work. Second, new commands and options are avaliable for Sashimi.

Update all plugins in your repository:

$ sashimi update --all

Install a plugin to your Rails app:

$ sashimi install --rails click-to-globalize
NOTE this is an alias for the add command.

Update a plugin of a Rails app:

$ sashimi update --rails click-to-globalize
NOTE If your application is versioned with Svn or Git, Sashimi will automatically schedules for add/remove the added/removed files.

How To Update

$ (sudo) gem update jodosha-sashimi --source=http://gems.github.com

I hope you enjoy those addictional options.

Sashimi: A Rails Plugins Manager Gem 3

Posted by luca
on Monday, May 19

I have a really, really bad memory: each time I need to install a Rails plugin, I Google to find the repository, then try to download the code. Often, I remember the url, but the server is down. Damn!

All this annoying issues kill the Rails rapidity on application prototyping. But, what if all the plugins which I need are available offline on my notebook? I can forget about all that urls, and I should stop to worry about the server status.

To solve this problems, I wrote Sashimi, it's a gem that manages you favourite Rails plugins in a local repository.

How It Works?

First you need to install it with:

$ (sudo) gem install jodosha-sashimi --source=http://gems.github.com

Now you can install a plugin on your local repository:
$ sashimi install git://github.com/jodosha/click-to-globalize.git

Ta-daaaa!! Now Click to Globalize is available offline:
$ sashimi list

click-to-globalize

If you need to add it to your Rails app, just move to your app root, then type:
$ sashimi add click-to-globalize

Conclusion

I found Sashimi really useful, I hope you too.

For the complete reference, please check out at the official gem page.

Ruby: XML Parsing With SAX 3

Posted by luca
on Wednesday, January 30

SAX is an event-driven parser for XML.

It sequentially reads the xml and generates special events. So, if you want to use SAX, you should implement the code to handle them. It's quite different from the DOM model, where the whole xml is parsed and loaded in an tree.
As you can see, the first approach is more difficult than the DOM one. Why we should use it? Depends.
If you want to extract certain informations from a big file, probably you should choose a SAX implementation, in this way you can avoid the initial DOM loading overhead.

The Ruby XML Library

The Ruby core library has a built-in XML parser (both DOM and SAX) called REXML, but it's terribly slow, it's highly advisable to use libxml. It's a binding to the popular library from Gnome and it was released as gem.

The Ruby Implementation

In first instance we need an handler, to deal with the SAX events.

class Handler
  def method_missing(method_name, *attributes, &block)
  end
end

Libxml generates several events and it expects to find certain methods into the class assigned ad handler. With method_missing we simply avoid any exception.

A More Useful Example

We try to extract the most recent headlines of a blog.

Download the feed:

curl http://feeds.feedburner.com/LucaGuidi >> luca.xml

Now we need our custom SAX parser:

require 'rubygems'
require 'xml/libxml'
require 'handler'

class SaxParser
  def initialize(xml)
    @parser = XML::SaxParser.new
    @parser.string = xml
    @parser.callbacks = Handler.new
  end

  def parse
    @parser.parse
    @parser.callbacks.elements
  end
end

We have just wrapped the SAX parser from libxml and we have registered our first class as callback handler.

Now we are going to improve the handler to recognize and save the post titles:

class Handler
  attr_accessor :elements

  def initialize
    @elements = []
  end

  def on_start_element(element, attributes)
    @print = true if element == 'title'
  end

  def on_characters(characters = '')
    @elements << characters if @print
  end

  def on_end_element(element)
    @print = false
  end

  # Handle all missing methods of the SAX events chain.
  # You can implement or omit one or many of those methods, without any raising Exception.
  # 
  # The complete chain is:
  #   on_start_document
  #   on_processing_instruction(instruction, arguments)
  #   on_start_element(element, attributes)
  #   on_characters(characters = '')
  #   on_end_element(element)
  #   on_end_document
  def method_missing(method_name, *attributes, &block)
  end
  end

When the handler is instantiated we create an internal array to store our results, then when we find and title element we set on true the print flag. When it's true we can store the data into elements, then we set on false on the ending handler of the element.

Usage

We create a trivial script:

#!/usr/bin/env ruby
require 'sax_parser'

xml = open(ARGV[0], 'r').collect { |l| l }.join
puts SaxParser.new(xml).parse

From the shell:

./parse luca.xml

Conclusion

SAX is less elegant and easy than DOM, but could be very useful in certain cases.

Ruby: How To Avoid A respond_to? Call 0

Posted by luca
on Wednesday, January 02

I'm writing this post as contribution to the Campagna Anti-IF (Anti-IF Campaign).

Problem

I'm developing an internal Rails plugin for widgets, it provides a class called Widget (really unconventional :-P), and each widget should inherit from it.
The actual implementation provides a callback called before_render, that allows to add some logic to a widget, if implemented it's called before the widget rendering.

Ruby doesn't have abstract methods, so I have to check if the subclass has the implementation of mentioned method:

# Rendering code..
before_render if respond_to? :before_render
# ...

As you can see it's an inefficient and inelegant way to render the widget, cause we always check if the method was implemented, and because I have introduced an if statement.

Solution

I added to Widget an empty before_render method: if the method it wasn't implemented into the subclass the rendering code will be safely called.
Here the new code:

def before_render
end

# Rendering code..
before_render
# ...

Ruby: Read A File With One Line Of Code 3

Posted by luca
on Tuesday, November 27

This snippet shows how to read a file and puts all the lines into an array.

f = *open('file.txt').map {|l| l.rstrip}
  # => ["Hi, from the", "txt file."]

Explanation

The open method returns an IO object, that include the Enumerable module, now we can just use #map (or #collect).

The splat operator is only a sugar syntactical shortcut for map

.

Ruby: How to check the operating system 0

Posted by luca
on Friday, October 05

Today I'm finishing the code cleanup for my latest Rails plugin (will be soon released) and I want to execute some rake tasks, only if the OS supports certain system calls.

The following snippet helps to check the current platform.

# (c) 2007 Luca Guidi (www.lucaguidi.com) - Released under MIT License.
# This code was inspired by Prototype rake test tasks.
require 'webrick'

class OperatingSystem
  class << self
    def host
      Config::CONFIG['host']
    end
  
    def macos?
      host.include?('darwin')
    end

    def linux?
      host.include?('linux')
    end
  
    def windows?
      host.include?('mswin')
    end
    
    def current
      case 
        when macos?:   'macos'
        when linux?:   'linux'
        when windows?: 'windows'
        else           'unknown'
      end
    end
  end
end

Play random files with Ruby 0

Posted by luca
on Friday, March 02
I've written a class to play random files, you can define the player path and allowed file extentions.
It will search recursively for all readable files, starting from execution from the folder passed as argument or, if miss, from current folder. Tested on a linux box with mplayer.

Usage:
$ ./shuffle
# play recursively all files from current folder
$ ./shuffle /path/to/files
# play recursively all files from specified folder


That's the source code.
#!/usr/bin/ruby

player = "/usr/local/bin/mplayer"
formats = ["mp3", "ogg", "flv"]
folder = ARGV[0] || ""

class ShufflePlayer
  @files
  @frx
  @player
  def initialize(player, formats, folder)
    @player = player
    gen_regex(formats)
    load_files(folder) 
  end
 
  def play
    flag = 1
    while flag && @files.length > 0
      flag = system("#{@player} -quiet #{@files.delete(@files[rand(Time.now) % @files.length])}")
    end
  end
  
  private
  def load_files(folder)
    @files = Dir[folder+'**/*.*'].reject!{|f| f if @frx.match(f).nil? || !File.readable?(f) }
    @files.collect!{|f| f.gsub(/['"\-\s\[\]\(\)]/){ |m| "\\"+m }} unless @files.nil?
  end
  
  def gen_regex(formats)
    @frx = /(#{formats.join('|')})$/
  end
end

ShufflePlayer.new(player,formats,folder).play


Security disclaimer: this code is strong insecure, i've posted for study purpouses, I'm not responsable if someone use it to attack your system.