# 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?
check for user input and handle blanks
August 30th, 2007Ruby Hack to toggle touchpad on your notebook
August 14th, 2007Well, 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, 2007Sequel 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,
ffset,: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, 2007I 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.