Mar 11

Mysql 4.x and Rails : RELEASE SAVEPOINT issue

Today with a project using mysql 4.1.22 that I have to implement some tests, I ran this error with rails 2.3.5 and I think for 2.3.x branch.

Mysql::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘RELEASE SAVEPOINT active_record_1′ at line 1: RELEASE SAVEPOINT active_record_1

RELEASE SAVEPOINT is for Mysql 5.x

It is also described here http://groups.google.com/group/rubyonrails-talk/browse_thread/thread/be0bece7cdf052fa?fwc=1

I get it resolved when digging into the activerecord code :
ActiveRecord::ConnectionAdapters::AbstractAdapter defines release_savepoint method.

To get around with this, just add the belowing patch after Rails was loaded (at the bottom of your config/environment.rb for instance)

# As of mysql 4.x does not support "RELEASE SAVEPOINT" statement
if ActiveRecord::Base.connection.instance_variable_get("@connection").get_server_info < '5.0'
  ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
    # Unset release savepoint method 
    def release_savepoint
    end
  end
end

Hope that this can help !

Oct 08

gettext 2.0.4 and rails 2.3.4

Rails 2.3.4 broke gettext_activerecord 2.0.4

Well I did not test other gems of the mutoh gettext set of libraries but here is the gulty code that breaks rails.
Since Activerecord::Errors changed its implementation a bit, an error like this is raised :

NoMethodError: undefined method `gsub' for #<ActiveRecord::Error:0x00000002919738>
        from /home/hallelujah/Jail/lib/ruby/gems/1.9.1/gems/gettext_activerecord-2.0.4/lib/gettext_activerecord/validations.rb:165:in `localize_error_message'
        from /home/hallelujah/Jail/lib/ruby/gems/1.9.1/gems/gettext_activerecord-2.0.4/lib/gettext_activerecord/validations.rb:112:in `block (2 levels) in each_with_gettext_activerecord'
        from /home/hallelujah/Jail/lib/ruby/gems/1.9.1/gems/gettext_activerecord-2.0.4/lib/gettext_activerecord/validations.rb:112:in `each'
        from /home/hallelujah/Jail/lib/ruby/gems/1.9.1/gems/gettext_activerecord-2.0.4/lib/gettext_activerecord/validations.rb:112:in `block in each_with_gettext_activerecord'
        from /home/hallelujah/Jail/lib/ruby/gems/1.9.1/gems/gettext_activerecord-2.0.4/lib/gettext_activerecord/validations.rb:112:in `each_key'
        from /home/hallelujah/Jail/lib/ruby/gems/1.9.1/gems/gettext_activerecord-2.0.4/lib/gettext_activerecord/validations.rb:112:in `each_with_gettext_activerecord'

You can add this piece of code after your gems and rails are loaded (e.g at the bottom of config/environment.rb )

module ActiveRecord
  class Errors
    def localize_error_message_with_patch(attr,obj, append_field)
      obj = obj.respond_to?(:message) ? obj.message : obj
      localize_error_message_without_patch(attr,obj,append_field)
    end
    alias_method_chain :localize_error_message, :patch
  end
end

I think I will patch gettext_activerecord and the muto gettext set of library to fit in rails 2.3.4
Maybe I may keep an eye on Rails 3.0 development.

Oct 02

Ordered Hash by keys

Recently, I have to implement my own Hash sorting method. Not really with Hash but with ActiveSupport::OrderedHash

      I don’t like the way ActiveSupport::OrderedHash behaves with sorting functionality.
      It just behaves like a simple Hash
      I would like that sort return an ActiveSupport::OrderedHash not an Arrray!!! Why is it called OrderedHash in this case ?
      I would like to sort with keys only, not with an array [key, value]

Ok no matter, I implemented my own new SimpleOrderedHash :

require 'active_support/ordered_hash'
class SimpleOrderedHash < ActiveSupport::OrderedHash
 
  # Lets reimplement sort method
  def sort(&block)
    h = self.dup
    h.sort!(&block)
    h
  end
 
  # Lets implement sort! method
  # It uses @keys variable to do the sorting
  def sort!(&block)
    @keys.sort!(&block)
    sync_keys!
    self
  end
 
  # A fancy inspect   
  def inspect
    "#<#{self.class.name} #{Hash.instance_method(:inspect).bind(self).call}>"
  end
end

You can now use it like that :

h = SimpleOrderedHash.new
h.merge!({'second' => 1, 'first' => 5, 'third' => 2.5})
=> #<SimpleOrderedHash {"third"=>2.5, "second"=>1, "first"=>5}>
 
# sort return a SimpleOrderedHash
result = h.sort do |a,b|
  h[a] <=> h[b]
end
=> #<SimpleOrderedHash {"third"=>2.5, "second"=>1, "first"=>5}>
 
# and order as I wanted
result.each{ |k,v| puts v }
1
2.5
5
=> ["second", "third", "first"]
 
# sort! change internally the order of a SimpleOrderedHash
h.sort! do |a,b|
  h[b] <=> h[a]
end
h.each{ |k,v| puts v }
5
2.5
1
=> ["first", "third", "second"]

Sep 24

Wake up with Amarok and Kalarm ( or cron ) and qdbus

Well it is not ruby tip. Just a Linux and KDE tip.

I am playing with dbus and wonder if I can wake up with kalarm and amarok under KDE.
The answer is YES!!!

PS : I plan to use ruby implementation of D-Bus and make some apps with it.
let see if I have time for that …
I see that ruby-dbus project is not very active but if you have information about implementations of dbus, please leave a comment or send me an e-mail.

# ! /bin/bash
 
# Variable declaration
 
interval=20
increment=10
volume=30
volumemax=100
 
# Body of the script
 
amarok # Launch Amarok application
qdbus org.kde.amarok /Player Stop #Stop amarok
qdbus org.kde.amarok /Player VolumeSet $volume #Set the volume to initial value of $volume
qdbus org.kde.amarok /Player Play # Play some music
 
while [ "$volume" -lt "$volumemax" ] ; do
 
qdbus org.kde.amarok /Player VolumeSet $volume # Set the volume
 
volume=$(expr $volume + $increment) # Increase volume variable
 
sleep $interval # Wait 20 seconds
 
done 
 
qdbus org.kde.amarok /Player VolumeSet $volumemax # Set volume to its maximum

You can just save this code to a file named amarokalarm.sh and add it to kalarm.

I think you can execute this file with a cron job (DON’T FORGET to add environment variable DISPLAY=:0.0 )

Sep 23

Inspectable accessors

Hey, it’s been a while I posted here.

So what’s the purpose ? I commonly use script/console to debug my rails applications. Today I wanted to see the values of my custom attributes model without typing model.custom_attribute. So I took a look at ActiveRecord::Base#inspect method. and the default inspect method shows me database fields. Well, let’s do some work to inspect custom attributes.
Say you have a users table with some fields : login,name,encrypted_password.

class User < ActiveRecord::Base
  attr_accessor :heroic_action
end
superman = User.find(1).inspect
superman.heroic_action = "Save the widow and the orphan"
pp superman.inspect
"#<User login: "Superman",  name: "Clark Kent",
          encrypted_password: "da39a3ee5e6b4b0d3255bfef95601890afd80709">"

Well I also want to know what heroic_action is superman doing. So i have to overwrite inspect method but I would like a DRY solution. That’s why I wrote this code :

EDIT: Just a small change to have inheritance work.

require 'active_support/core_ext/class'
 
module InspectableAttributes
 
  def self.included(base)
    base.class_inheritable_array :inspectable_attributes , :instance_writer => false
    base.extend(ClassMethods)
    base.inspectable_attributes = []
    base.class_eval do 
 
      def inspect
        inspected_values = respond_to?(:attributes_before_type_cast) ? attributes_before_type_cast.map{|k,v| "#{k.to_s}:  #{v.inspect}" } : []
        inspected_values.concat(self.class.inspectable_attributes.map { |attr| "#{attr}: #{send(attr).inspect}" })
        "#<#{self.class.name} #{inspected_values.join(', ')}>"
      end
 
    end
  end
 
  module ClassMethods
    def inspectable_attr_accessor(*args)
      attr_accessor(*args)
      self.inspectable_attributes |= args.map(&:to_s)
    end
  end
 
end
class User < ActiveRecord::Base
  include InspectableAttributes
  inspectable_attr_accessor :heroic_action
end

That’s what I was looking for !!!

superman = User.find(1).inspect
superman.heroic_action = "Save the widow and the orphan"
pp superman.inspect
"#<User login: "Superman",  name: "Clark Kent",
             encrypted_password: "da39a3ee5e6b4b0d3255bfef95601890afd80709",
             heroic_action: "Save the widow and the orphan">"

Note that this code can be used in any ruby code requiring ‘active_support/core_ext/class’.

Jul 24

Blocks are Proc : Les procédures Proc et les blocks en ruby.

( For non-french readers : I am not giving up writing in english … Read the next post! )

Si vous venez d’un autre langage, le terme procédure (associé au terme fonction) doit vous dire quelque chose. Vaguement ….

Allez quelques connaissances (méconnaissances) tirées de ma mémoire pour poser les bases.

Par exemple, en PHP il existe deux types de fonctions. Les fonctions natives (built-in) et les fonctions “codées” par l’utilisateur.
Ces dernières se séparent en deux types : les fonctions et les procédures.

La différence entre les deux ? Une procédure est un groupe d’instructions qui ne renvoie pas de valeur. Une fonction est une procédure qui renvoie une valeur.

Et ruby dans tout ça ??

C’est complètement différent et je dirai même plus les procédures Ruby sont très éloignés des procédures PHP. En ruby il n’y a que des objets (les méthodes sont des objets) et les méthodes renvoient toujours une valeur.
Vous avez déjà vu ou même codé des choses comme ceci :

[1,2,3,4,5,6].each do |nb|
  # Un code quelconque : des instructions ...
end

C’ette méthode est native à Enumerable (module que la classe Array inclut)
La méthode Array#each prend 0 paramètre mais un block. Le block est tout ce qui se trouve entre do et end.
On pourrait le représenter en Ruby comme ceci :

def each(&block)
  # Un truc compliqué à écrire en ruby
end

Ne vous y trompez pas “&block” n’est pas un argument. C’est la notation ruby pour dire que la méthode each s’accompagne obligatoirement d’un block.

Autre exemple :

class Bar
 
  def my_proc(&procedure)
     @foo_proc = procedure
  end
 
  def recall
    @foo_proc.call
  end
end
 
bar = Bar.new
bar.my_proc do
# Pas de code
end
 #=> #<Proc:0x00000>

Il se trouve que la procédure est une instance de la classe Proc.
Sans trop de surprise mêmes les procédures sont des objets. Et oui, en ruby tout est objet.

Quel est l’intérêt me direz-vous?

Cela change tout !!! En PHP les prcoédures sont codées en dur, en ruby on peut générer à la volée des suites d’instructions sans pour autant avoir à implémenter une méthode !!!

Illustration :

On sait que les blocks sont des instances de la classe Proc. La solution est facile, il suffit de créer des instances de Proc et les passer comme blocks d’une méthode acceptant un block.

p1 = Proc.new do
 puts "Je suis p1"
end
 
p2 = Proc.new do
  puts "Je suis p2"
end
 
bar = Bar.new
bar.my_proc(&p1)
# Je suis p1
#=> nil
bar.foo_proc 
#=> #<Proc:0x164564ab>
 
bar.recall
# Je suis p1
#=> nil
 
bar.my_proc(&p2)
# Je suis p2
#=> #<Proc:0x054ecdab>
 
bar.recall
# Je suis p2
#=> nil
 
bar2 = Bar.new
bar2.my_proc(&p2)
# Je suis p2
#=> #<Proc:0x054ecdab>
 
bar2.instance_eval("@foo_proc") == bar.instance_eval("@foo_proc") 
#=> true

Vous avez compris l’intérêt? Les blocks sont bien des suites d’instructions mais plus que cela, ce sont des objets !!! L’illustration précédente montre qu’on peut partager des suites d’instructions entre différents objets, générer ces instructions dynamiquement !

En route pour la méta-programmation avec Ruby !!!

Jul 10

Class : to_s or not to_s ? That is the name !

Many rubyist use the method Class#to_s instead of Class#name

My purpose (shared by some programmers) is that to_s is just a String representation of the Class not its name!!

Imagine you want to store an ordered list of inherited subclasses as a String so you can retrieve the inheritance order of each subclass.

class Parent
  @@subclasses = []
  def self.inherited(subclass)
    @@subclasses << "#{subclass}"
  end
 
  def self.inheritance_order
    @@subclasses.index("#{self}")
  end
end
 
class Child1 < Parent
end
 
class Child2 < Parent
end
 
# etc ...

And now you want to know, the inheritance order of Child2

Child2.inheritance_order
#=> 1

As long as you don’t override Child2.to_s method, this works.

But if you decide to override it ….

 
def Child2.to_s
  "The second child of Parent"
end
 
Child2.inheritance_order
#=> nil

Do you understand what I mean ? My purpose is that Class#to_s is a String representation, so you can do what you want with this method (as long as it returns a String instance)

If you want to write something more reliable, just change Class#to_s by Class#name :

class Parent
  @@subclasses = []
  def self.inherited(subclass)
    @@subclasses << subclass.name
  end
 
  def self.inheritance_order
    @@subclasses.index(self.name)
  end
end

What is your opinion ?

Jul 08

Opening

Hi!

This is the first time I open my own blog. I am so sorry to be french. Even if this blog is written in both language (french and english) I will write mostly in english. But mine is not perfect. Sorry about that, but it is one of the way I have found to improve my written english. Please tell me where I am doing wrong!!

Nevertheless, this blog is not just for me a way to write more english. I also decided to share my experience as a programmer, precisely as a Ruby programmer.

Wait! I am not a guru, just a beginner. I aim at becoming a master. And my purpose is that if I share my experiences with you then you may share your knowledge with me.

That is why I beg you to inform me what I am doing wrong and why (in english writing and ruby programming). I ask you to share with me.

So let’s go legally Peer-2-Peering!

Pour les francophones :

Le but de ce blog est de partager mes connaissances avec vous et que vous partagiez avec moi (et les autres internautes) vos connaissances.

N’hésitez pas à me reprendre si j’ai fait une faute d’anglais, de français et de programmation ou si vous avez même une façon plus jolie d’écrire dans ces langues et langages.

» Newer posts