Table of Contents

Code Samples

Outputting the Alphabet

    <% "A".upto("Z") do |c| %>
      <li <%= 'class="current"' if (session['wordlist'] == c.downcase) %>>
        <%= link_to '<span>' + c + '</span>', {:action => 'list', :character => c.downcase} %>
      </li>              	
    <% end %>

Keyword Search (In MySQL)

@words = Word.find(:all, :conditions => [" root LIKE CONCAT('%',CONCAT(:keyword,'%')) ", {:keyword => keyword}])

How to Divide or Split an Array (Or how to Turn One Array into Multiple Arrays)

This code adds a ”/” instance method to the Array class.

class Array
  def / pieces    
    len = self.length;
    mid = (len/pieces)
    chunks = []
    start = 0
    1.upto(pieces) do |i|
      last = start+mid
      last = last-1 unless len%pieces >= i
      chunks << self[start..last] || []
      start = last+1
    end
    chunks            
  end
end

(I didn't invent this myself, but I've lost the url to the original code. If you're the author, or you know the author, please contact me and I'll put in a link here).

Suppose you have a an array of words which you want to output in two columns. Here's how to do this, using our ”/” method:

left, right = *(@words / 2)

The “*” operator is called the splat operator, or sometimes the splash operator. As is explained here the splat operator takes an array and pulls the contents out of the array. You can use the splat operator to simplify this code:

  why = [:lucky, :stiff, :with, :chunky, :bacon]
  v1 = why[0]
  v2 = why[1]
  v3 = why[2]
  v4 = why[3]
  v5 = why[4]

To this code:

  why = [:lucky, :stiff, :with, :chunky, :bacon]
  v1,v2,v3,v4,v5 = *why

Update (20071104): the splat / splash operator returns a copy. Otherwise, a reference is returned. In other words, this code – without splat/splash – will also work:

  why = [:lucky, :stiff, :with, :chunky, :bacon]
  v1,v2,v3,v4,v5 = why

I can't find a real difference between using the splat/splash operator, and not using it, though:

irb(main):001:0> a = Array.new()
=> []
irb(main):002:0> a.push(:first)
=> [:first]
irb(main):003:0> a.push(:second)
=> [:first, :second]
irb(main):004:0> my_first,my_second = a
=> [:first, :second]
irb(main):005:0> puts "my_first: #{my_first}"
my_first: first
=> nil
irb(main):006:0> my_first.equal?(a[0])
=> true
irb(main):007:0> my1, my2 = *a
=> [:first, :second]
irb(main):008:0> puts "my1: #{my1}"
my1: first
=> nil
irb(main):009:0> my1.equal?(a[0])
=> true
irb(main):010:0> b = ['e1','e2']
=> ["e1", "e2"]
irb(main):011:0> split_a1, split_a2 = b
=> ["e1", "e2"]
irb(main):012:0> split_a1.equal?(b[0])
=> true
irb(main):013:0> split_b1, split_b2 = *b
=> ["e1", "e2"]
irb(main):014:0> split_b1.equal?(b[0])
=> true

This seems to indicate that a reference is returned in all cases.

How to Return All Elements of an Array Up to An Unknown Point

The Array object comes with various handy methods, such as collect or select to create a subset. But recently I ran into a problem: how do you return all elements up till and including the element that meets your search criteria?

Usually this is not very hard. If your set is ordered by some criterion, you just use select:

# Find all future rock concerts
scheduled_concerts = rock_concerts.select {|rc| rc.date > Date.today}

But now suppose that your set is ordered, but by many criteria. Of course, you could use multiple conditions in the body of the select method. But now suppose that you already have the id of the object which is your right limit. The following code snippet exemplifies this:

  @completed_exercises = Array.new
  
  if (not @saved_game.nil?)        
    @scheduled_exercises.each do |s|
      @completed_exercises.push(s.id)
      break if s.id == @saved_game.scheduled_exercise_id
    end
  end

Here, I needed both the entire set of available exercises (@scheduled_exercises, retrieved elsewhere), as well as the set of completed exercises (@completed_exercises).