Skip to content

Ruby Blender

  • Blog
  • About
  • Archives
  • Log in
 
Less
More
Trim
Untrim
« Older
Home
Loading
Newer »
Archive for the 'metaprogramming' Category
01Sep09 Default values for Attributes
metaprogramming programming ruby
0 Comments

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 2290

Warning: implode() [function.implode]: Argument must be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3242

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3306

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 2290

Warning: implode() [function.implode]: Argument must be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3242

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3306

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3643

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3651

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3654

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 1925

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 2290

Warning: implode() [function.implode]: Argument must be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3242

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3265

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3306

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3357

Warning: array_keys() [function.array-keys]: The first argument should be an array in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

Warning: Invalid argument supplied for foreach() in /home/aetheric/public_html/blender/wp-content/plugins/devformatter/geshi/geshi.php on line 3502

This is the first in a series of entries which I’m pulling over articles from an old blog, revising, etc…

The Problem

One of the neat things about Ruby is it’s ability to create accessor methods for you, by simply declaring attr_reader, attr_writer, or attr_accessor.  However, there’s not an easy way to define a default value for an attribute.  The original version of this code was based off of Create getter and setter on a valorized variable and ideas from Ruby Quiz #67: Metakoans.  The main difference between it and Sandro Paganotti’s version is that you can pass in a block which will be evaluated each time it is invoked (in case the value might depend on something else).  Additionally, it will work with boolean types.

The Solution

  |  copy code |? 
01
class Object
02
  def self.attribute(*arg,&block)
03
    (name, default) = arg
04
    short_name = name.to_s.sub(/\?/,"")
05
    self.send(:define_method, name) {
06
      if instance_variables.include? "@#{short_name}"
07
           self.instance_eval "@#{short_name}"
08
      else
09
        if block_given?
10
          instance_eval &block
11
        else
12
          default
13
        end
14
      end
15
    }
16
    self.send(:define_method, "#{short_name}="){ |value|
17
      self.instance_eval "@#{short_name} = value"
18
    }
19
  end
20
end
21

 

In order to use it, you could do something like this:

  |  copy code |? 
1
class Foo
2
  attribute :bar
3
  attribute(:fud) {instance_variables.include?("@bar") ? @bar : ' '}
4
  attribute :fi, 10
5
  attribute :flag?, true
6
end
7

And, in action, it would look like this:

  |  copy code |? 
01
>> f=Foo.new
02
=> #<Foo:0x2ad8c6af7728>
03
>> f.bar # defined, but not set to anything (nil)
04
=> nil
05
>> f.fud # since bar is not defined, return an empty space
06
=> " "
07
>> f.fi # just return the default
08
=> 10
09
>> f.flag? # and here's a boolean
10
=> true
11
>> f.bar = 5 # now we set bar
12
=> 5
13
>> f.fud # Since bar is set, then fud will return its value
14
=> 5
15
>> f.fud = 20 # now we explicitly set fud, and the block is no longer used
16
=> 20
17
>> f.fud # fud returns 20 as expected
18
=> 20
19
>> f.bar # and, as expected, changing fud has no effect on bar
20
=> 5
21

 

There might be a better way to do this; but one of the things I love about Ruby is that you can add new features to the language very easily.

Enhanced by Zemanta
 
Browse Archives ยป
  • administrivia (2)
  • configuration (1)
  • metaprogramming (1)
  • mini-saga (5)
  • programming (10)
  • rails (1)
  • ruby (15)
  • rubygems (2)
  • Uncategorized (1)
 

Recent Posts

  • Default values for Attributes
  • Arguments with Trollop
  • Database Paranoia — ActiveRecord Callbacks
  • Ruby Bindings and Scope
  • What’s #method_missing missing?

Search

Browse by Category

  • administrivia (2)
  • configuration (1)
  • metaprogramming (1)
  • mini-saga (5)
  • programming (10)
  • rails (1)
  • ruby (15)
  • rubygems (2)
  • Uncategorized (1)

Browse by Tag

  • ActiveRecord
  • binding
  • Command-line interface
  • gotcha
  • irb
  • irbc
  • Languages
  • Library
  • Local variable
  • metaprogramming
  • mini-saga
  • paradigm
  • philosophy
  • programming
  • rails
  • Recursion
  • ruby
  • rubygems
  • Ruby on Rails
  • scope
  • utilities

Browse by Month

  • September 2009 (1)
  • August 2009 (4)
  • April 2009 (1)
  • February 2009 (11)
 
 
  • Blog
  • About
  • Archives
  • Log in
 


Theme Design by Jay Kwong | Powered by WordPress and K2

 

Home Top Archives Entries FeedComments Feed