Useful Blogs II: Presentation Matters

Posted by Matt Williams

And some links to specific articles:

Useful Blogs I: Web Development and Design

Posted by Matt Williams

Here's a list of some blogs I've found useful:

map_by_method

Posted by Matt Williams

If you have a collection of objects, such as an array of students, and you want to quickly and easily capture their names, you can use: students.map_by_name which will return the names of the students as an array. This is a ruby gem and you can find more information about it at: map_by_method

Find or Create

Posted by Matt Williams

I found myself recently typing code like:
1
2

foo = Bar.find(:first, :conditions => {:name => "Fred"}) || Bar.new(:name => "Fred")
As it turns out, there's a rails method for this: Model.find_or_create_by_COLUMN, where COLUMN is the name of the column.

(Not) Helpful Helpers

Posted by Matt Williams

In Rails 2.0.x, application.rb has a:

1
2

helper :all
which has the effect of including all the helpers. In general, this is helpful. However, if you want to have different behaviour in different controllers, this can cause problems, because only one behaviour will be available for all controllers. And the behaviour seems linked to the default load order (alphabetical) -- that said, if you have two controllers FooController and BarController, then the helpers will be loaded in the following order:
  1. ApplicationHelper
  2. BarHelper
  3. FooHelper

So, if you expect to have different behaviours in Foo and Bar, you'll be disappointed. The behaviours override each other, leaving a single behaviour across the application. In order to fix this, remove or comment out the declaration in application.rb.

cheat

Posted by Matt Williams

Cheaters never win, or do they?

Ruby2Ruby

Posted by Matt Williams

Ruby2Ruby is a gem which allows you to look at the code of a class. To install do:
gem install ruby2ruby
(you may need to do a sudo in front of it)

Here's an example of its use:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'ruby2ruby'
=> true
irb(main):003:0> class Foo
irb(main):004:1> def fud
irb(main):005:2> puts "groo"
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):008:0> Ruby2Ruby.translate Foo
=> "class Foo < Object\n  def fud\n    puts(\"groo\")\n  end\nend"
irb(main):009:0> class Foo
irb(main):010:1> def fi
irb(main):011:2> puts "fo"
irb(main):012:2> end
irb(main):013:1> end
=> nil
irb(main):014:0> Ruby2Ruby.translate Foo
=> "class Foo < Object\n  def fi\n    puts(\"fo\")\n  end\n  \n  def fud\n    puts(\"groo\")\n  end\nend"
irb(main):015:0> class Foo
irb(main):016:1> def fud
irb(main):017:2> puts "Hello World!"
irb(main):018:2> end
irb(main):019:1> end
=> nil
irb(main):020:0> Ruby2Ruby.translate Foo
=> "class Foo < Object\n  def fi\n    puts(\"fo\")\n  end\n  \n  def fud\n    puts(\"Hello World!\")\n  end\nend"
irb(main):021:0>

Notice how it changes the class output. One thing I have found is that if you create instance variables outside of a method they won't show up in the output. Otherwise, it works quite well and is a good addition to a metaprogramming toolkit.

sub vs sub!

Posted by Matt Williams

sub does not do the same thing as sub!:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

irb(main):001:0> a="something"
=> "something"
irb(main):002:0> b=a.sub(/e/,"E")
=> "somEthing"
irb(main):003:0> b
=> "somEthing"
irb(main):004:0> a
=> "something"
irb(main):005:0> c=a.sub!(/thing/,"one")
=> "someone"
irb(main):006:0> c
=> "someone"
irb(main):007:0> a
=> "someone"
irb(main):008:0> b=a.sub(/thing/,"body")
=> "someone"
irb(main):009:0> b
=> "someone"
irb(main):010:0> c=a.sub!(/thing/,"body")
=> nil

They behave the same when there is a pattern matched and a change, however, when there is not a pattern matched they behave differently. This can cause grief as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13

irb(main):011:0> a="something"
=> "something"
irb(main):012:0> b=a.tr("n-za-m","a-z")
=> "fbzrguvat"
irb(main):013:0> b=a.sub(/thing/,"one").tr("n-za-m","a-z")
=> "fbzrbar"
irb(main):014:0> a
=> "something"
irb(main):015:0> b=a.sub!(/body/,"one").tr("n-za-m","a-z")
NoMethodError: undefined method `tr' for nil:NilClass
        from (irb):15
        from :0

This is the general behaviour of any method ending in !, so be careful when you are using them.

xargs

Posted by Matt Williams

The UNIX command /bin/find is useful, particularly its exec flag. However, for each invocation of the exec it spawns a sub process. xargs is much more efficient; it will spawn only so many as are needed -- it does this based on the size of the command line. For instance, if there are 1000 matches to a find, then find would fork 1000 subprocesses, whereas xargs would do far fewer, perhaps even as few as one.

The other useful thing about xargs is you can use it when you an glob (such as *) returns too many matches. Instead of some command * you could do ls * | xargs some command.

Super!

Posted by Matt Williams

One common mistake people make with ruby's method_missing is to leave out a super. This means that if you don't handle all the cases which could cause an invocation of method_missing then the exception will be lost. So, always include super, unless you have a good reason not to do so.

ksh hash

Posted by Matt Williams

This describes a hashing implementation within ksh.

DateTime to Seconds since Epoch

Posted by Matt Williams

Here's how to convert ruby DateTIme objects to the seconds since the epoch:
1
2
3
4
5
6
7
8
9
10

>> d=DateTime.now
=> Thu, 03 Jan 2008 15:49:21 -0500
>> t=Time.parse(d.strftime("%c"))
=> Thu Jan 03 15:49:21 -0500 2008
>> t.to_f
=> 1199393361.0
>> t.to_f.floor
=> 1199393361
>> 

Hashing properties

Posted by Matt Williams

This is just a simple piece of code to create a hash of the values of properties of a Ruby object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

class Object                    # All objects will inherit this method
  def make_hash
    h={ }                       # start out with a "known quantity"
    self.instance_variables.each do |v| # for each instance variable do
      # Instance variables start with an @, so strip it
      v.sub!(/@/,"")

      # add our key/value pair to the array only if the variable has
      # been exposed
      h[v] = self.send(v) if self.respond_to? v
    end
    h                           # return the hash
  end
end

Ok, let's test it out:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

$ irb
>> load 'nifty.rb'
=> true
>> "a".instance_variables
=> []
>> "a".make_hash
=> {}
>> class Foo
>>   attr_reader :bar, :fud
>>   def initialize
>>     @bar="Hello World"
>>     @fud=123
>>     @groo = Time.now
>>   end
>> end
=> nil
>> f=Foo.new
=> #<Foo:0xb7857174 @groo=Wed Jan 02 10:20:36 -0500 2008, @fud=123, @bar="Hello World">
>> f.instance_variables
=> ["@groo", "@fud", "@bar"]
>> f.make_hash
=> {"bar"=>"Hello World", "fud"=>123}
>> quit

Note that although Foo has three instance variables, only two of those have been exposed (the attr_reader line).

vi global substitution

Posted by Matt Williams

Something old, something new. vi has been around for almost 30 years, and it seems fitting to start the year with it. vi has what many would consider a cryptic command set, but for all of its age is still quite powerful.

In order to do a global substitution in vi, type the following (escaped if necessary) outside of insert mode:

:%s/from/to/g
  • % specifies to look on all lines.
  • s says to substitute.
  • /from/to/ is the pattern which specifies what is being replaced, as well as its replacement
  • g specifies that it is a global replacement, that is, all instances on a line, not just the first, are replaced.

Beginnings

Posted by Matt Williams

This is designed to be a section which offers daily tips & techniques. They can be from a variety of languages and subject areas.