<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: attribute code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sun, 18 May 2008 02:31:57 GMT</pubDate>
    <description>DZone Snippets: attribute code</description>
    <item>
      <title>Adding helpful error messages to your Ruby code</title>
      <link>http://snippets.dzone.com/posts/show/5446</link>
      <description>This Ruby code raises an error if the XPath query fails because the attribute being queried did not exist for the given element. &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  def map_pattr(node, fieldx, valuex)&lt;br /&gt;    begin&lt;br /&gt;    parameter = node.root.elements["parameter[@field='#{fieldx}']"]&lt;br /&gt;    parameter.add_attribute('value', valuex)&lt;br /&gt;    parameter&lt;br /&gt;    &lt;br /&gt;    rescue&lt;br /&gt;      puts 'feedpopulated.rb: map_attr() the field ' + fieldx + ' was not found in params.'&lt;br /&gt;      raise&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Notice that a raise statement is used to ensure that the system error message is raised and any further code execution is halted.&lt;br /&gt;&lt;br /&gt;Without adding a customized helpful message I would be left scratching my head trying to work out what the following system error message meant.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;./feedpopulated.rb:27:in `map_pattr': undefined method `add_attribute' for nil:NilClass (NoMethodError)&lt;br /&gt;     from ./feedpopulated.rb:51:in `create_record'&lt;br /&gt;     from ./feedpopulated.rb:49:in `each'&lt;br /&gt;     from ./feedpopulated.rb:49:in `create_record'&lt;br /&gt;     from ./recordx.rb:91:in `call_create'&lt;br /&gt;     from ./s3fileuploader_handler.rb:14:in `call'&lt;br /&gt;     from ./s3fileuploader_handler.rb:40:in `invoke'&lt;br /&gt;     from ./uploadtwitteraudio.rb:22:in `initialize'&lt;br /&gt;     from /usr/lib/ruby/1.8/rexml/element.rb:890:in `each'&lt;br /&gt;     from /usr/lib/ruby/1.8/rexml/xpath.rb:53:in `each'&lt;br /&gt;     from /usr/lib/ruby/1.8/rexml/element.rb:890:in `each'&lt;br /&gt;     from ./uploadtwitteraudio.rb:18:in `initialize'&lt;br /&gt;     from ./uploadtwitteraudio.rb:72:in `new'&lt;br /&gt;     from ./uploadtwitteraudio.rb:72&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Reference: &lt;a href="http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_exceptions.html"&gt;Programming Ruby: The Pragmatic Programmer's Guide - Exceptions, Catch, and Throw&lt;/a&gt; [ruby-doc.org]</description>
      <pubDate>Wed, 30 Apr 2008 11:40:47 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5446</guid>
      <author>jrobertson (James Robertson)</author>
    </item>
    <item>
      <title>Display a filtered list using XSLT</title>
      <link>http://snippets.dzone.com/posts/show/5177</link>
      <description>Following on from the post &lt;a href="http://snippets.dzone.com/posts/show/5174"&gt;A simple XSLT example&lt;/a&gt; [dzone.com], this code lists all files which have the type 'rb' (equivalent to ls *.rb).&lt;br /&gt;&lt;br /&gt;file: dir.xsl&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;?xml version="1.0"?&gt;&lt;br /&gt;&lt;br /&gt;&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;&lt;br /&gt;      &lt;br /&gt;    &lt;xsl:template match="dir"&gt;&lt;br /&gt;    &lt;div id="articles"&gt;&lt;br /&gt;      &lt;ul&gt;&lt;br /&gt;      &lt;xsl:apply-templates select="records/file[@type='rb']"/&gt;&lt;br /&gt;      &lt;/ul&gt;&lt;br /&gt;    &lt;/div&gt;&lt;br /&gt;    &lt;/xsl:template&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;xsl:template match="records/file[@type='rb']"&gt;&lt;br /&gt;      &lt;li&gt;&lt;xsl:value-of select="."/&gt;&lt;/li&gt;&lt;br /&gt;    &lt;/xsl:template&gt;&lt;br /&gt;    &lt;br /&gt;&lt;/xsl:stylesheet&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;output:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;div id='articles'&gt;&lt;br /&gt;  &lt;ul&gt;&lt;br /&gt;    &lt;li&gt;projxmlhelper.rb&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;feedpopulated.rb&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;squrl_handler.rb&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;password_handler.rb&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;category.rb&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;gwd.rb&lt;/li&gt;&lt;br /&gt;  &lt;/ul&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;*update 11:58am 26-Feb*&lt;br /&gt;Here's a filter I will be using in my projects&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;?xml version="1.0"?&gt;&lt;br /&gt;&lt;br /&gt;&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;&lt;br /&gt;      &lt;br /&gt;    &lt;xsl:template match="dir"&gt;&lt;br /&gt;    &lt;div id="articles"&gt;&lt;br /&gt;      &lt;ul&gt;&lt;br /&gt;      &lt;xsl:apply-templates select="records/file"/&gt;&lt;br /&gt;      &lt;/ul&gt;&lt;br /&gt;    &lt;/div&gt;&lt;br /&gt;    &lt;/xsl:template&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;xsl:template match="records/file"&gt;&lt;br /&gt;      &lt;xsl:if test="@type=$type"&gt;&lt;br /&gt;        &lt;li&gt;&lt;xsl:value-of select="."/&gt;&lt;/li&gt;&lt;br /&gt;      &lt;/xsl:if&gt;&lt;br /&gt;    &lt;/xsl:template&gt;&lt;br /&gt;    &lt;br /&gt;&lt;/xsl:stylesheet&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Tue, 26 Feb 2008 11:47:59 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5177</guid>
      <author>jrobertson (James Robertson)</author>
    </item>
    <item>
      <title>Specifying default values with Ruby's attr_reader and attr_accessor</title>
      <link>http://snippets.dzone.com/posts/show/4382</link>
      <description>Dependency injection in Ruby is as easy as falling off a log. As &lt;a href="http://weblog.jamisbuck.org/2007/7/29/net-ssh-revisited#comment-2734"&gt;Jamis Buck has pointed out&lt;/a&gt;, DI is a good thing, but DI frameworks for Ruby are overkill. The language makes them unnecessary.&lt;br /&gt;&lt;br /&gt;Here's how to enhance attr_reader and attr_accessor so that they can receive an options hash for specifying the default value of an attribute.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;module AttrWithDefaultExtension&lt;br /&gt;  &lt;br /&gt;  module ClassMethods&lt;br /&gt;    &lt;br /&gt;    def attr_accessor(*args)&lt;br /&gt;      attrs, attrs_with_defaults = split_for_last_hash(args)&lt;br /&gt;      attrs_with_defaults.each do |name, default|&lt;br /&gt;        attr_reader_with_default name, default&lt;br /&gt;        attr_writer              name&lt;br /&gt;      end&lt;br /&gt;      &lt;br /&gt;      super(*attrs)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def attr_reader(*args)&lt;br /&gt;      attrs, attrs_with_defaults = split_for_last_hash(args)&lt;br /&gt;      attrs_with_defaults.each do |name, default|&lt;br /&gt;        attr_reader_with_default name, default&lt;br /&gt;      end&lt;br /&gt;      &lt;br /&gt;      super(*attrs)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;  private&lt;br /&gt;    &lt;br /&gt;    def attr_reader_with_default(name, default)&lt;br /&gt;      define_method(name) do&lt;br /&gt;        unless instance_variable_defined?("@#{name}")&lt;br /&gt;          default = default.call(self) if default.kind_of?(Proc)&lt;br /&gt;          instance_variable_set "@#{name}", default&lt;br /&gt;        end&lt;br /&gt;        instance_variable_get "@#{name}"&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def split_for_last_hash(args)&lt;br /&gt;      if args.last.kind_of?(Hash)&lt;br /&gt;        [args[0...-1], args.last]&lt;br /&gt;      else&lt;br /&gt;        [args, {}]&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def self.included(other_module)&lt;br /&gt;    other_module.extend ClassMethods&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Object; include AttrWithDefaultExtension; end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here are the unit tests. They demonstrate not only the enhanced behavior of attr_reader and attr_accessor, but also that the standard behavior remains unbroken.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;require 'test/unit'&lt;br /&gt;&lt;br /&gt;module AttrWithDefaultExtensionTest&lt;br /&gt;  &lt;br /&gt;  class TwoStandardAttrReaders &lt; Test::Unit::TestCase&lt;br /&gt;    &lt;br /&gt;    attr_reader :foo, :baz&lt;br /&gt;    &lt;br /&gt;    def test_should_not_define_first_instance_variable&lt;br /&gt;      assert_equal false, instance_variable_defined?(:@foo)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_return_first_instance_variable_when_sent_first_attr_reader&lt;br /&gt;      @foo = 'bar'&lt;br /&gt;      assert_equal 'bar', foo&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_not_define_second_instance_variable&lt;br /&gt;      assert_equal false, instance_variable_defined?(:@baz)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_return_second_instance_variable_when_sent_second_attr_reader&lt;br /&gt;      @baz = 'bat'&lt;br /&gt;      assert_equal 'bat', baz&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  class TwoStandardAttrAccessors &lt; Test::Unit::TestCase&lt;br /&gt;    &lt;br /&gt;    attr_accessor :foo, :baz&lt;br /&gt;    &lt;br /&gt;    def test_should_not_define_first_instance_variable&lt;br /&gt;      assert_equal false, instance_variable_defined?(:@foo)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_return_first_instance_variable_when_sent_first_attr_reader&lt;br /&gt;      @foo = 'bar'&lt;br /&gt;      assert_equal 'bar', foo&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_set_first_instance_variable_when_sent_first_attr_writer&lt;br /&gt;      self.foo = 'bar'&lt;br /&gt;      assert_equal 'bar', @foo&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_not_define_second_instance_variable&lt;br /&gt;      assert_equal false, instance_variable_defined?(:@baz)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_return_second_instance_variable_when_sent_second_attr_reader&lt;br /&gt;      @baz = 'bat'&lt;br /&gt;      assert_equal 'bat', baz&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_set_second_instance_variable_when_sent_second_attr_writer&lt;br /&gt;      self.baz = 'bat'&lt;br /&gt;      assert_equal 'bat', @baz&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  class TwoStandardAttrReadersAndADefault &lt; Test::Unit::TestCase&lt;br /&gt;    &lt;br /&gt;    attr_reader :foo, :baz, :blit =&gt; 'blat'&lt;br /&gt;    &lt;br /&gt;    def test_should_not_define_first_instance_variable&lt;br /&gt;      assert_equal false, instance_variable_defined?(:@foo)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_return_first_instance_variable_when_sent_first_attr_reader&lt;br /&gt;      @foo = 'bar'&lt;br /&gt;      assert_equal 'bar', foo&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_not_define_second_instance_variable&lt;br /&gt;      assert_equal false, instance_variable_defined?(:@baz)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_return_second_instance_variable_when_sent_second_attr_reader&lt;br /&gt;      @baz = 'bat'&lt;br /&gt;      assert_equal 'bat', baz&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_not_define_third_instance_variable&lt;br /&gt;      assert_equal false, instance_variable_defined?(:@blit)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_set_third_instance_variable_when_sent_third_attr_reader&lt;br /&gt;      blit&lt;br /&gt;      assert_equal 'blat', @blit&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_not_set_third_instance_variable_if_already_set_when_sent_third_attr_reader&lt;br /&gt;      @blit = 'splat'&lt;br /&gt;      assert_equal 'splat', blit&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  class TwoStandardAttrAccessorsAndADefault &lt; Test::Unit::TestCase&lt;br /&gt;    &lt;br /&gt;    attr_accessor :foo, :baz, :blit =&gt; 'blat'&lt;br /&gt;    &lt;br /&gt;    def test_should_not_define_first_instance_variable&lt;br /&gt;      assert_equal false, instance_variable_defined?(:@foo)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_return_first_instance_variable_when_sent_first_attr_reader&lt;br /&gt;      @foo = 'bar'&lt;br /&gt;      assert_equal 'bar', foo&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_set_first_instance_variable_when_sent_first_attr_writer&lt;br /&gt;      self.foo = 'bar'&lt;br /&gt;      assert_equal 'bar', @foo&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_not_define_second_instance_variable&lt;br /&gt;      assert_equal false, instance_variable_defined?(:@baz)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_return_second_instance_variable_when_sent_second_attr_reader&lt;br /&gt;      @baz = 'bat'&lt;br /&gt;      assert_equal 'bat', baz&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_set_second_instance_variable_when_sent_second_attr_writer&lt;br /&gt;      self.baz = 'bat'&lt;br /&gt;      assert_equal 'bat', @baz&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_not_define_third_instance_variable&lt;br /&gt;      assert_equal false, instance_variable_defined?(:@blit)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_set_third_instance_variable_when_sent_third_attr_reader&lt;br /&gt;      blit&lt;br /&gt;      assert_equal 'blat', @blit&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_not_set_third_instance_variable_if_already_set_before_sent_third_attr_reader&lt;br /&gt;      @blit = 'splat'&lt;br /&gt;      assert_equal 'splat', blit&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_set_third_instance_variable_when_sent_third_attr_writer&lt;br /&gt;      self.blit = 'splat'&lt;br /&gt;      assert_equal 'splat', @blit&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  class AProcDefault &lt; Test::Unit::TestCase&lt;br /&gt;    &lt;br /&gt;    attr_accessor :my_object_id =&gt; Proc.new { |obj| obj.object_id }&lt;br /&gt;    &lt;br /&gt;    def test_should_not_define_instance_variable&lt;br /&gt;      assert_equal false, instance_variable_defined?(:@my_object_id)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_set_instance_variable_to_result_of_proc_when_sent_attr_reader&lt;br /&gt;      my_object_id&lt;br /&gt;      assert_equal object_id, @my_object_id&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_not_set_instance_variable_if_already_set_before_sent_attr_reader&lt;br /&gt;      @my_object_id = 'foo'&lt;br /&gt;      assert_equal 'foo', my_object_id&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_set_instance_variable_when_sent_attr_writer&lt;br /&gt;      self.my_object_id = 'foo'&lt;br /&gt;      assert_equal 'foo', @my_object_id&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  class AProcWithinAProcDefault &lt; Test::Unit::TestCase&lt;br /&gt;    &lt;br /&gt;    attr_accessor :my_proc =&gt; Proc.new { Proc.new { } }&lt;br /&gt;    &lt;br /&gt;    def test_should_not_define_instance_variable&lt;br /&gt;      assert_equal false, instance_variable_defined?(:@my_proc)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_set_instance_variable_to_result_of_outer_proc_when_sent_attr_reader&lt;br /&gt;      my_proc&lt;br /&gt;      assert_kind_of Proc, @my_proc&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_not_set_instance_variable_if_already_set_before_sent_attr_reader&lt;br /&gt;      @my_proc = 'foo'&lt;br /&gt;      assert_equal 'foo', my_proc&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_should_set_instance_variable_when_sent_attr_writer&lt;br /&gt;      self.my_proc = 'foo'&lt;br /&gt;      assert_equal 'foo', @my_proc&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 02 Aug 2007 14:03:03 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4382</guid>
      <author>njonsson (Nils Jonsson)</author>
    </item>
  </channel>
</rss>
