Tech Talk

Bytefull of Tech Talk (http://tech.bytefull.com)

Posts under the 'Ruby' Category

Little Things about Ruby Strings

August 6th, 2007 by ahsan

Here are some things about Ruby Strings that may have escaped your attention - if you were introduced to Ruby via Rails

Efficiency

Since Ruby scans double-quoted strings for variables and escape sequences, it’s more efficient to use single-quotes for raw strings:

@sentence = 'Jackdaws love my big sphinx of quartz'
redirect_to :index => 'action'

Pretty Please, with sugar on top …

Split your strings across multiple lines. No backslashes required (sorry, couldn’t resist that !).

sql_query = "SELECT [column]
                 FROM [table]
                 WHERE [condition]
-- sql comment goes here"

or

# Q = double-quotes, embed variables 
# q = single-quotes
sql_query = %Q{SELECT @columnname
                 FROM @tablename
                 WHERE @conditions}
# You may use [ < or (as delimiters instead of {

ASCII code

To obtain the ASCII code for a character, prefix it with a question-mark:

puts ?B
# => 66

Convert it back to a string with:

puts 66.chr
# => "B"

Concatenation

Use the << operator to concatenate strings. Where += or + create a new copy, << appends to an existing string. Hence, it is more efficient:

existing << " end"

Instead of:

existing += " end"

(source)

Index a string with a regexp

You can test a string like this:

email = "spamandbakedbeans@skit.org"
if email[/@/]
  puts "I found the first @"
end

And this replaces the first match

string = "jackdaws love my big sphinx of quartz"
string[/a/] = 'A'
# => jAckdaws love my big sphinx of quartz

This replaces the second match

string = "jackdaws love my big sphinx of quartz"
string[/(j).+(z)/, 2] = "Z"
# => jackdaws love my big sphinx of quartZ

Remember, the regexp matches the entire string

Convert hex to integer (sort of)

Given a string representation of a hexadecimal, String.hex returns the corresponding integer:

puts "0x7b".hex # you can omit 0x if you wish
# => 123

Multiply a string

puts "<br />" * 3
# => "<br /><br /><br />"
Filed under Rails, Ruby having 2 Comments »

Hack: Redefine a rails model for a rake task

June 17th, 2007 by ahsan

Well, this is weird.

I wrote a rake task to import data from a csv file (output from a legacy system) into my development database for testing. The catch was that I wanted to extend my model class by adding a custom method only in the rake file.

require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
 
class Customer < ActiveRecord::Base
  def my_custom_method
  end
end

But here, for some reason, rake tries to define a _new_ activerecord model, not redefine the existing model I’ve written. So, what I tried was to precede the class definition with:

c = Customer.new # which really goes to waste

and it worked ! Rake now recognizes that I’m trying to add a method to my existing rails model !

Filed under Code, Rails, Ruby having No Comments »

style2inline.rb (for html newsletters)

June 3rd, 2007 by ahsan

Dreamweaver CS 3 has a facility to rearrange inline styles in a <style> tag. Well, here’s a utility that does the opposite: it converts css in style tags to inline css. Yeah, I hear you. Why would anyone want to do that ?!

Sending HTML Newsletters is a nightmare. Most of the email clients, bar Eudora Light, support css. However, not all properties are supported, and Gmail, one of the major web-based email clients, supports only inline styles.

You need Ruby, and Hpricot installed to run this. Duh, it runs on windows too !

EDIT: fixed a bug & added NOTES

Here’s the code:

#!/bin/env ruby
# style2inline.rb - v0.2
# http://tech.bytefull.com
 
# NOTES:
# CSS must not contain any comments
# the last attribute-value pair must end in a semi-colon, example:
#  a {font-family: Verdana; font-size: 18pt;}
 
# uncomment this if you have hpricot installed as a gem
# require 'rubygems'
require 'hpricot'
 
def style_to_inline(filename)
  doc = open(filename) {|f| Hpricot(f)}
  css = ""
  elems = doc.search('head/style')
  # combine the content of all style tags
  elems.map {|x| css &lt;&lt; x.inner_html}
  # remove the style tags - we don't need them in our output doc
  elems.remove
  # collapse all newlines
  css.gsub!("\n", " ")
  # Regexp by Nick Franceschina
  # http://regexlib.com/REDetails.aspx?regexp_id=916
  dec_block = '((\s*([^,{]+)\s*,?\s*)*?){((\s*([^:]+)\s*:\s*([^;]+?)\s*;\s*)*?)}'
  regexp = Regexp.new(dec_block, Regexp::IGNORECASE)
  results = css.scan(regexp)
  results.each do |res|
    res[0].split(',').each do |css_sel|
      doc.search(css_sel.strip).each do |elem|
        if elem.elem? # added in version 0.2,
                      # to avoid operating on a Hpricot::Text element
          if elem[:style] then
            # append to the existing style information
            elem[:style] = elem[:style] + res[3]
          else
            # add a style attribute
            elem[:style] = res[3]
          end
          # we don't need the class attribute
          elem.remove_attribute(:class)
        end
      end
    end
  end
# output
  File.open("s2i_#{filename}", 'w') {|file| file.write(doc) }
end
 
ARGV.each {|x| style_to_inline(x)}

Invoke it with ruby style2inline.rb [FILENAME], and it will output a file of the same name prepended with ’s2i’, e.g s2i-filename.html.

Filed under Code, Ruby having No Comments »