Madison Rails
Exploring Ruby Methods

Here is the code for my very quick exploration of a few common idioms in Ruby methods. This will make more sense if you copy and paste the whole thing into your favorite ruby editor:

class PostModule

  # show a post via method call, no args
  def present_post
    self.post.to_s
  end

  # show post a post passed in
  # present_post(post)
  # present_post post
  def present_post(post)
    post.author + " " + post.created_at.to_s
  end

  #
  # ex: present_post(post, false)
  # present_post post 
  #
  def present_post(post, show_date = true)
    if show_date
      post.author + " " + post.created_at.to_s
    else
      post.author
    end
  end

  #
  # defaults can be any valid ruby, ie other method calls, 
  #
  def present_post(post, show_date = (display_date? && other_stuff? && 1 ==1))
    if show_date
      post.author + " " + post.created_at.to_s
    else
      post.author
    end
  end

  # the "splat" operator allows variable arguements
  # it must be used as the last argument in the method,
  # and will "sponge" up all remaining args into an array
  # present_post post
  # present_post, name
  # present_post, name, age, parents, etc...
  def present_post(post, methods*)
    str = post.author
    methods.each {|meth| str << post.send(meth) } if methods
    str
  end

  #
  # simulate named parameters in Ruby
  # present_post(post, :foo => "bar")
  # present_post(post, some_options)
  # present_post post, :show_date => true, :div => "post_div" 
  #
  def present_post(post, options = {})
    str = post.author
    str << " " << post.created_at.to_s if options[:show_date]
    str << " " << post.content if options[:show_content]
    str
  end

  # named parameters with defaults using reverse_merge (part of ActiveSupport)
  #
  def present_post(post, options = {})
    options.reverse_merge! :show_date => true, :show_content => false
    str << " " << post.created_at.to_s if options[:show_date]
    str << " " << post.content if options[:show_content]
    str
  end

  # present posts - note the plural
  # allows one model object or an Array of posts to be passed in
  # 
  def present_posts(arg, options = {})
    options = { :show_date => true, :show_content => false }.merge(options)
    posts = Array(arg)
    str = "" 
    posts.each do |post|
      str << post.author
      str << " " << post.created_at.to_s if options[:show_date]
      str << " " << post.content if options[:show_content]
      str
    end
  end

# arg can be a primary key, a last name, or posts
  def present_posts(arg, options = {})
    options = { :show_date => true, :show_content => false }.merge(options)
    case arg
      when Integer then posts = Post.find_by_id(arg)
      when String  then posts = Post.find_by_last_name(arg)
      else posts = Array(post)
    end
    str = "" 
    posts.each do |post|
      str << post.author
      str << " " << post.created_at.to_s if options[:show_date]
      str << " " << post.content if options[:show_content]
      str
    end
  end

end