published on 18.05.2007 00:18.

flickr.phillipoertel.com

just gave my flickr api toys a little overhaul. check them out. more coming soon, for example entering your username to show your contacts’ photos, instead of mine.

Posted in , ,  | no comments

published on 18.04.2007 13:37.

"This path leads to the gates of madness."

»Because if itself is an expression, you can get really obscure with statements such as:«

if artist == "John Coltrane"
  artist = "'Trane"
end unless nicknames == "no"

from the original pickaxe by dave thomas.

Posted in ,  | Tags , , ,  | 1 comment

published on 18.03.2007 11:20.

ruby: performance comparison of rexml and libxml

update: here’s the same for PHP’s XML Parser.

a quick comparison of the two libraries available for processing XML in ruby shows dramatic performance differences.

am i missing something, is there a fundamental flaw in the test? of course REXML is pure ruby, while libxml is C; but can the difference really be so huge?

loading an xml file

file size libxml REXML factor
10KB 0,83 39,17 47,0
100KB 6,67 306,56 46,0
1.6MB 71,88 3954,21 55,0

simple xpath expression

file size libxml REXML factor
10KB 0,12 124,68 1004,7
100KB 0,67 678,11 1016,8
1.6MB 6,21 22578,18 3633,6

the test code

def benchmark
   start = Time.new.to_f
   10.times { yield }
   puts ((Time.new.to_f - start) / 10) * 1000
end

doc = nil

# exclude the effect of filesystem caching (makes sense?)
File.read('products.xml')

#
# libxml
#
require 'rubygems'
require 'xml/libxml'

benchmark do
   doc = XML::Document.file("products.xml")
end

benchmark do
   doc.find('//articles/article/shortdesc').each do |node|
      #puts node.content
   end
end

#
# rexml
#
require "rexml/document"

benchmark do
   doc = REXML::Document.new File.read("products.xml")
end

benchmark do
   doc.elements.each("//articles/article/shortdesc") do |node| 
      #puts node.text
   end
end

Posted in , ,  | Tags , , , ,  | no comments

published on 13.12.2006 17:12.

unix: finding files older than x days

find all files older than 60 days:

find /some/dir -atime +60

in combination with xargs this is very useful for removing old rails sessions:

find /u/apps/my_app/current/tmp/sessions/ -atime +60 | xargs rm

Posted in ,  | no comments

published on 22.09.2006 22:32.

smoke this.

the following code execudes just fine (the puts are executed in order 1-7, no parse errors). earns an anything-special-about-that? shrug from the ruby crowd, a highly disturbed look from everyone else (including me).

module Acid
    puts "1) My first Acid."    
    def self.append_features(mod)
        puts "4) Now #{mod.class}'s taken Acid."
        mod.extend(self)
    end
  end

class Bus
    puts "2) Now that's a boring bus."
end

class Furthur < Bus
    puts "3) First, setup the fuel."
    include Acid
    puts "5) Lets get on the magic bus."
    def initialize
        puts "6) A magic bus has been set up."
    end
    def play_hippie_music
        puts "7) Driving Home. That's it, folks!"
    end
end

magic_bus = Furthur.new
magic_bus.play_hippie_music

Posted in ,

published on 08.06.2006 13:45.

getting themes to work with typo trunk

the old web server is dying, so it was time to get a new one and move everything over. typo didn’t run in the new ruby/rails environment, so i decided to try updating to the latest svn trunk revision. it took some fiddling to get it to work, especially since i wanted to use a new theme – [Lucid Theme](http://typogarden.com/articles/2005/11/30/the-lucid-theme) by [Jamie Hill](http://www.thelucid.com/). the theme hasn’t been updated for some time, so (due to some changes in the handling of sidebars) it didn’t work with typo trunk. fak3r [researched](http://fak3r.com/articles/2006/06/05/howto-get-typo-themes-to-work-with-trunk) how to fix that – thanks!

note: there’s still some trouble with internet explorer on windows. i’ll look into that – and the flickr sidebar – later.

Posted in ,  | Tags , ,

published on 02.04.2006 19:56.

getting irb brackets to work on german windows

for those on windows, there’s the great ruby one-click installer which will set up a nice ruby environment on your box. asking it to take care of all possible localization issues would be asking for too much though, so if you’re on a non-english windows, chances are that irb will be severely broken – no brackets, no ruby joy. and no script/console in ruby on rails.

the reliable way

here’s how i was able to fix the issue:

  • download the file linked to in why’s poignant guide to ruby in the “windows hickups” sidebar. place the files from the zip file in ruby directories as described at why’s.
  • get the text snippet “for europeans” as well. save it to the file c:\ruby\etc\.inputrc_german. (you will have to create the etc directory first). when saving the file you might have to go through the windows shell, as the windows explorer doesn’t let you create filenames starting with a dot.
  • tell readline where to find this file. the safest bet is to directly point at the file by setting the INPUTRC environment variable. so edit c:\ruby\bin\irb.bat and insert the following after the @echo off command (line 2):
    set INPUTRC=c:\ruby\etc\.inputrc_german

the pretty way

if you don’t want to “hack around” your ruby directory and modify irb.bat, of course you can specify the environment variable somewhere else and also put the .inputrc file in another directory. these are your options (start reading from the paragraph “Readline-4.0 will look for an …”).

i fiddled with this a lot, so i came up with the first option. if you want to put the file somewhere else, be aware of the following:

  • the HOME env variable is most likely not set on windows, so readline will not search there.
  • if the path to .inputrc contains spaces (as it will when pointing to a german windows home dir - “C:\Dokumente und Einstellungen...”) readline might choke. at least it didn’t work on my box.
  • if you happen to have cygwin installed (as i do …) there’s some extra confusion, as the HOME env variable is set, but it points to some place that (at least on my system) does not exist.

Posted in ,

published on 13.03.2006 00:59.

Ruby tip of the day (2)

Comparing objects in Ruby

UPDATE: the title is a bit misleading, it should better be “sorting ruby objects” or something like that. the point is to show that ruby’s collections have several methods to compare their contents - and that the comparison rule can be given in a block.

you have a couple of objects in a collection. you want to find out which of the objects has the highest position.


class SomeFoo
  attr_reader :age
  def initialize(age)
    @age = age
  end
end

list = [
  SomeFoo.new(45),
  SomeFoo.new(18),
  SomeFoo.new(29)
]

oldest_foo =  list.max {|a,b| a.age <=> b.age}
puts oldest_foo.age
=> 45

of course this comparison works for anything you can write a block for.

Posted in ,

published on 28.02.2006 20:31.

Ruby tip of the day

EDIT (11.11.2007): Dir#glob (aliased as: Dir[]) could also be used.

find all files in a directory matching some pattern

list = Dir.new('.').entries.select { |f| f =~ /_\d{2}.(jpg|gif)$/ }
=> ["11-029_42.jpg", "1209-180_32.jpg", "1210-180_32.jpg", "1218-180_32.jpg"]

list.size
=> 4

Posted in ,  | Tags

published on 31.01.2006 23:25.

completely useless ruby code

this chunk of code is completely useless, apart from the fact that it let me practise how ruby does arrays, objects, constants, observers and singletons. and how to pass a variable number of arguments to a function method and set defaults for arguments that weren’t passed. plus it had me thinking about “what-goes-where” and coupling in object oriented programming.

maybe not so useless after all!

#
# for documentation see the UML diagram at the following url
# @url <a href="http://www.flickr.com/photos/calicojane/93113537">http://www.flickr.com/photos/calicojane/93113537</a>
#
require 'observer'
require 'singleton'

class StickFigure
   MALE = 0
   FEMALE = 1   
   attr_reader :name
   def initialize(attrs)
      @name     = attrs[:name] ||= 'Anonymous Coward'
      @sex      = attrs[:sex] ||= MALE
      @is_lazy  = attrs[:is_lazy] ||= false
      @in_peril = false
   end
   def in_peril!
      @in_peril = true
      puts @name + ' is in peril!'
   end
   def to_s
      puts "\nHi! I'm " + @name + ' and I am ' + (@is_lazy == true ? 'a little' : 'not') + ' lazy.'
   end   
   alias :introduce_self :to_s   
end

class CoffeeDrinkingStickFigure < StickFigure
   def have_coffee
      puts @name + ' has a cup of coffee.'
      pot = get_coffee_pot
      pot.pour_coffee
      if pot.needs_refill?
         make_more_coffee unless @is_lazy
      end
      return_to_desk
   end

   #
   # :TODO: the stickfigure should NOT be responsible for notifying it's observer ... better solution?
   # this part is not so pretty.
   # 
   def return_to_desk
      puts @name + ' returns to ' + (@sex == FEMALE ? 'her' : 'his') + ' desk.'
      get_coffee_pot.notify_observers(get_coffee_pot, self)
   end   
   def make_more_coffee
      puts @name + ' refills the coffee pot.'
      pot = get_coffee_pot
      pot.refill
   end   
   private
   def get_coffee_pot
      CoffeePot.instance
   end   
end

class CoffeePot
   include Singleton
   include Observable
   attr_reader :cups_left
   CUPS_WHEN_FULL = 2.5   
   def initialize
      @cups_left = 0
      self.refill
      self.add_observer(BigBrother.new)
   end   
   def pour_coffee
      @cups_left -= 1
      changed
   end   
   def refill
      @cups_left = CUPS_WHEN_FULL
      changed
   end
   def is_empty?
      @cups_left == 0
   end   
   def needs_refill?
      @cups_left < 1
   end   
end

class BigBrother
   def update(pot, who_got_coffee)
      if pot.needs_refill?
         puts 'The coffee pot needs a refill and ' + who_got_coffee.name + " didn't refill it!\n"
         who_got_coffee.in_peril!
      else 
         cup_string = pot.cups_left == 1 ? 'is 1 cup' : 'are ' + pot.cups_left.to_s + ' cups'
         puts "There #{cup_string} of coffee left."
      end
   end
end

stick_figures = [
   CoffeeDrinkingStickFigure.new(:name => 'Miss Piggy', :sex => StickFigure::FEMALE),
   CoffeeDrinkingStickFigure.new(:name => 'Bert'),
   CoffeeDrinkingStickFigure.new(:name => 'Kermit', :is_lazy => true),
   CoffeeDrinkingStickFigure.new(:name => 'Ernie', :is_lazy => true)
]

stick_figures.each do |stick_figure|
   stick_figure.introduce_self
   stick_figure.have_coffee
end

Posted in , ,  | Tags , ,

Older posts: 1 2 3