check for user input and handle blanks

August 30th, 2007
# If you have been programming for all these sickening years, you would have used something like this quite often.

# You are reading user input and it might be having extra spaces, newlines god knows what at the ends, so you write code like this:

foo_data = nil
t_data = nil

# your evil user may have entered only white spaces as input so better you strip them out
if param[:from_data]
  t_data = param[:from_data].strip
else
  t_data = param[:from_data]
end

unless t_data.empty?
  foo_data = param[:from_data].strip
else
  foo_data = "Some other default value you want"
end
# now you can use foo_data without any fear.



# Follows a real clean implementation of above code, checkout the number of lines reduced.

# Lets first modify the ruby Object class system itself.
class Object
  def nob
    if respond_to?(:empty?)
      return nil if empty?
      if respond_to?(:strip)
        return (strip.empty?) ? nil : (self.strip)
      end
      self
    else
      self
    end
  end
end

# Now above ruby_hack lets you write code like this:
foo_data = param[:from_data].nob || "Some other default value"

# it will detect if object is a string, then before checking whether string is empty or not, it will strip the white spaces
# from the string. #nob method would return nil if your object was 'blank', otherwise it will return the object itself
# by blank, i mean, if its a string, it shouldn't be nil or "   " or "\n",
# by blank, i mean, not a empty array like: []
# method is polymorphic in nature and operates on any ruby data type. and thats why, i put it in Object class itself.

# But above method is slightly costlier, that your hand cranked if, elses, because it uses ruby specific facility respond_to? for
# giving polymorphic behaviour and so what will you choose?

Ruby Hack to toggle touchpad on your notebook

August 14th, 2007

Well, my Dell 1520 didn’t have a button to toggle touchpad and when you are coding your way to glory, the touchpad comes in your way and slows you down. Here is a hack, that toggles the touchpad. Save it in your ~/bin/ directory and enjoy:

#!/usr/bin/env ruby

touchpadout = `synclient -l`
touchpadout.split("\n").each do |b_output|
  next unless b_output =~ /TouchPadOff/i
  key,t_value = b_output.split('=')
  value = t_value.strip.to_i
  if value == 0
    system("synclient TouchPadOff=1")
  else
    system("synclient TouchPadOff=0")
  end
end

Model hack for Sequel

August 13th, 2007

Sequel is sweet. Those of us, who do not want a beast like ActiveRecord in their hair pin sized projects, its a godsend. Now, as you hack away at your application you will soon realize that, perhaps ActiveRecord models was also not bad. It gives very good code separation.

So, I wrote a stupid ugly hack that implements a model around Sequel. Now Sequel already provides one and you may ask why reinvent. It was mainly because I was bamboozled by their model implementation and couldn’t understand it mostly.

I have added couple of thingies to ruby core and they are neatly tucked away in a file called “ruby_hacks.rb”. Let me first show that, since its essential for our implementation:


# ruby_hacks.rb

class Hash
  def assert_valid_keys(*valid_keys)
    unknown_keys = keys - [valid_keys].flatten
    unless unknown_keys.empty?
      raise(ArgumentError, "Unknown key(s): #{unknown_keys.join(", ")}") 
    end
  end
end

class Object
  def deep_copy
    Marshal.load(Marshal.dump(self))
  end

  def nothing?
    if respond_to?(:empty?) && respond_to?(:strip)
      empty? or strip.empty?
    elsif respond_to?(:empty?)
      empty?
    elsif respond_to?(:zero?)
      zero?
    else
      !self
    end
  end
  def self.metaclass; class << self; self; end; end

  def self.iattr_accessor *args

    metaclass.instance_eval do
      attr_accessor *args
    end

    args.each do |attr|
      class_eval do
        define_method(attr) do
          self.class.send(attr)
        end
        define_method("#{attr}=") do |b_value|
          self.class.send("#{attr}=",b_value)
        end
      end
    end
  end
end

class Array
  def extract_options!
    last.is_a?(::Hash) ? pop : {}
  end
end

I hope above code is nothing fancy. iattr_accessor implements accessors around class instance variables.

Now lets implement, base class of our model, which will be inherited by all models:


# FIXME: someday it will be good to have method_missing hack, but essentianlly that would
# require some assumptions about database schema.

class DbConnection
  iattr_accessor :connection
  iattr_accessor :table_name

  VALID_FIND_OPTIONS = [:conditions, :include, :joins, :limit, :offset,:filter,:order, :select, :readonly, :group, :from, :lock ]

  def self.establish_connection(args = nil)
    options = { }
    if args.blank?
      options[:username] = ServerConfig['database']['username']
      options[:password] = ServerConfig['database']['password']
      options[:host] = ServerConfig['database']['host']
      options[:database] = ServerConfig['database']['database']
      options[:port] = ServerConfig['database']['port']
    elsif(args.is_a?(Symbol) or args.is_a? String)
      yml_string = args.to_s
      options[:username] = ServerConfig[yml_string]['username']
      options[:password] = ServerConfig[yml_string]['password']
      options[:host] = ServerConfig[yml_string]['host']
      options[:database] = ServerConfig[yml_string]['database']
      options[:port] = ServerConfig[yml_string]['port']
    end

    unless options[:port]
      @connection = 
          Sequel.open("mysql://#{options[:username]}:#{options[:password]}@#{options[:host]}/#{options[:database]}")
    else
      @connection = 
          Sequel.open("mysql://#{options[:username]}:#{options[:password]}@#{options[:host]}:#{options[:port]}/#{options[:database]}")
    end
  end

  establish_connection

  # if there is no connection object in current class go for parent class connection object
  def self.connection; @connection || self.superclass.connection; end

  class << self
    def set_table_name p_table_name
      @table_name = p_table_name.to_s
    end

    def execute p_sql_query
      connection.execute(p_sql_query)
    end

    def find(*args)
      options = args.extract_options!
      validate_find_options(options)
      case args.first
        when :first: find_first(options)
        when :all: find_all(options)
        else raise "Invalid find"
      end
    end

    def validate_find_options(options) #:nodoc:
      options.assert_valid_keys(VALID_FIND_OPTIONS)
    end

    def find_first(options)
      t_records = connection[table_name].filter(options[:filter]).limit(1)
      t_records[1] rescue nil
    end

    def find_all(options)
      connection[table_name].filter(options[:filter])
    end
  end

end

Now lets see couple of sample model implementations:


# user.rb
class User < DbConnection
  set_table_name :users
  def self.find_by_auth_id p_auth_id
    find(:first,:filter => { :feed_key => p_auth_id})
  end
end

Another one, where connection handler is overrideen:


class Ticker < DbConnection
  establish_connection :platform_db
  set_table_name :ubac_sym

  def self.symbol_search p_symbol
    find(:first,:filter => { :Symbol => p_symbol })
  end
end

Testing Emacs htmlize mode

July 19th, 2007
    def receive_data data
      @tokenizer.extract(data).each do |stock_data|
        $data_log.info "---------- #{stock_data}"
        @stock_data = UbacParser.new stock_data
        if @stock_data.valid_code?
          dispatch_request
        else
          send_error_without_callback "Invalid Protocol code"
        end
      end
    end

Blogging from Shire

July 14th, 2007

I am yet to decide on format of things that this new blog will contain. I am certainly not new to blogging, and have been attempting to blog for quite a while.