<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: Remvee's Code Snippets</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sun, 18 May 2008 06:32:50 GMT</pubDate>
    <description>DZone Snippets: Remvee's Code Snippets</description>
    <item>
      <title>Object.memoize</title>
      <link>http://snippets.dzone.com/posts/show/5300</link>
      <description>The following is inspired by the article "&lt;a href="http://blog.grayproductions.net/articles/caching_and_memoization"&gt;Caching and Memoization&lt;/a&gt;" by James Edward Gray II. &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# = Memoization for objects&lt;br /&gt;# &lt;br /&gt;# This module will extend +Object+ with the +memoize+ method.  This method&lt;br /&gt;# provides memoization for instance methods, which means return values will&lt;br /&gt;# be cached and subsequent calls will return the cached value of the first&lt;br /&gt;# call.&lt;br /&gt;# &lt;br /&gt;# Caching is done based on instance, method and arguments to the method.  All&lt;br /&gt;# data is kept in a single +Hash+ store which allows flushing all cached&lt;br /&gt;# results at ones using the +flush_memos+ method.&lt;br /&gt;# &lt;br /&gt;# == Example&lt;br /&gt;#   class Person &lt; Struct.new(:email)&lt;br /&gt;#     def finger&lt;br /&gt;#       `finger #{email}`&lt;br /&gt;#     end&lt;br /&gt;#     memoize :finger&lt;br /&gt;#   end&lt;br /&gt;#   &lt;br /&gt;#   bob = Person.new('bob@test.net')&lt;br /&gt;#   bob.finger                        # finger command executed&lt;br /&gt;#   bob.finger                        # cached value returned&lt;br /&gt;#   Memoizable.flush_memos&lt;br /&gt;#   bob.finger                        # finger command executed&lt;br /&gt;#&lt;br /&gt;# == See also&lt;br /&gt;# http://blog.grayproductions.net/articles/caching_and_memoization&lt;br /&gt;#&lt;br /&gt;# == Author&lt;br /&gt;# R.W. van 't Veer, 2008-04-01, Amsterdam&lt;br /&gt;module Memoizable&lt;br /&gt;  # Store for cached values.&lt;br /&gt;  CACHE = Hash.new{|h,k| h[k] = Hash.new{|h,k| h[k] = {}}} # 3 level hash; CACHE[:foo][:bar][:yelp]&lt;br /&gt;  &lt;br /&gt;  # Memoize the given method(s).&lt;br /&gt;  def memoize(*names)&lt;br /&gt;    names.each do |name|&lt;br /&gt;      unmemoized = "__unmemoized_#{name}"&lt;br /&gt;      &lt;br /&gt;      class_eval %Q{&lt;br /&gt;        alias   :#{unmemoized} :#{name}&lt;br /&gt;        private :#{unmemoized}&lt;br /&gt;        def #{name}(*args)&lt;br /&gt;          cache = CACHE[self][#{name.inspect}]&lt;br /&gt;          cache.has_key?(args) ? cache[args] : (cache[args] = send(:#{unmemoized}, *args))&lt;br /&gt;        end&lt;br /&gt;      }&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  # Flush cached return values.&lt;br /&gt;  def flush_memos&lt;br /&gt;    CACHE.clear&lt;br /&gt;  end&lt;br /&gt;  module_function :flush_memos&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;class Object # :nodoc:&lt;br /&gt;  extend Memoizable&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;if $0 == __FILE__&lt;br /&gt;  require 'test/unit'&lt;br /&gt;  &lt;br /&gt;  class MemoizeTest &lt; Test::Unit::TestCase # :nodoc:&lt;br /&gt;    def setup&lt;br /&gt;      @obj = TestObject.new&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def teardown&lt;br /&gt;      Memoizable.flush_memos&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_memoize_value_should_stick_until_cache_flushed&lt;br /&gt;      @obj.value = 'a'&lt;br /&gt;      assert_equal 'a', @obj.value&lt;br /&gt;      &lt;br /&gt;      @obj.value = 'b'&lt;br /&gt;      assert_equal 'a', @obj.value&lt;br /&gt;      &lt;br /&gt;      Memoizable.flush_memos&lt;br /&gt;      assert_equal 'b', @obj.value&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_flush_should_clear_all_cached_objects&lt;br /&gt;      @obj.value = 'yelp'&lt;br /&gt;      @obj.value&lt;br /&gt;      &lt;br /&gt;      assert_not_equal 0, Memoizable::CACHE.size&lt;br /&gt;      Memoizable.flush_memos&lt;br /&gt;      assert_equal 0, Memoizable::CACHE.size&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_memoize_should_keep_separate_cache_per_instance&lt;br /&gt;      other = TestObject.new&lt;br /&gt;      @obj.value, other.value = 'a', 'b'&lt;br /&gt;      &lt;br /&gt;      assert_equal 'a', @obj.value&lt;br /&gt;      assert_equal 'b', other.value&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_memoize_should_keep_separate_cache_per_method&lt;br /&gt;      @obj.value, @obj.other = 'a', 'b'&lt;br /&gt;      &lt;br /&gt;      assert_equal 'a', @obj.value&lt;br /&gt;      assert_equal 'b', @obj.other&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    def test_memoize_should_include_arguments_in_cache_key&lt;br /&gt;      @obj.with_arguments = 'a'&lt;br /&gt;      assert_equal 'a', @obj.with_arguments(:this)&lt;br /&gt;      &lt;br /&gt;      @obj.with_arguments = 'b'&lt;br /&gt;      assert_equal 'a', @obj.with_arguments(:this)&lt;br /&gt;      assert_equal 'b', @obj.with_arguments(:that)&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    class TestObject # :nodoc:&lt;br /&gt;      attr_accessor :value, :other&lt;br /&gt;      memoize :value, :other&lt;br /&gt;      &lt;br /&gt;      attr_writer :with_arguments&lt;br /&gt;      def with_arguments(*args); @with_arguments; end&lt;br /&gt;      memoize :with_arguments&lt;br /&gt;      &lt;br /&gt;      attr_writer :question&lt;br /&gt;      def question?; @question; end&lt;br /&gt;      memoize :question?&lt;br /&gt;      &lt;br /&gt;      attr_writer :exclamation&lt;br /&gt;      def exclamation!; @exclamation; end&lt;br /&gt;      memoize :exclamation!&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Tue, 01 Apr 2008 14:06:28 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5300</guid>
      <author>remvee (Remco van 't Veer)</author>
    </item>
    <item>
      <title>Simple cacher module for Rails</title>
      <link>http://snippets.dzone.com/posts/show/5297</link>
      <description>Illustration of a simple cacher module for Rails.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# lib/cacher.rb&lt;br /&gt;module Cacher&lt;br /&gt;  STORE = {}&lt;br /&gt;  &lt;br /&gt;  def cache(*args)&lt;br /&gt;    STORE[args.inspect] ||= yield&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def flush!&lt;br /&gt;    STORE.clear&lt;br /&gt;  end&lt;br /&gt;  module_function :flush!&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# app/models/person.rb&lt;br /&gt;class Person &lt; AR::Base&lt;br /&gt;  include Cacher&lt;br /&gt;&lt;br /&gt;  def finger&lt;br /&gt;    cache(:finger, email) do&lt;br /&gt;      `finger #{email}`&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# app/controller/application.rb&lt;br /&gt;class ApplicationController &lt; AC::Base&lt;br /&gt;  after_filter { Cacher.flush! }&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Tue, 01 Apr 2008 09:12:56 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5297</guid>
      <author>remvee (Remco van 't Veer)</author>
    </item>
    <item>
      <title>Persistent Rails cookie session</title>
      <link>http://snippets.dzone.com/posts/show/5173</link>
      <description>Session cookies, the Rails-2 kind, are transient because that's safer.  In some applications safety isn't important.  The following makes the session cookies persist for a year.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class ApplicationController &lt; ActionController::Base&lt;br /&gt;  before_filter :update_session_expiration_date&lt;br /&gt;&lt;br /&gt;private&lt;br /&gt;  def update_session_expiration_date&lt;br /&gt;    unless ActionController::Base.session_options[:session_expires]&lt;br /&gt;      ActionController::Base.session_options[:session_expires] = 1.year.from_now&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Mon, 25 Feb 2008 12:23:27 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5173</guid>
      <author>remvee (Remco van 't Veer)</author>
    </item>
    <item>
      <title>load all fixtures</title>
      <link>http://snippets.dzone.com/posts/show/5007</link>
      <description>In some test cases I need all my fixtures to be loaded.  To make this easier, add the following to test/test_helper.rb:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Test::Unit::TestCase&lt;br /&gt;  def self.all_fixtures&lt;br /&gt;    Dir[File.dirname(__FILE__) + "/fixtures/*.yml"].each do |f|&lt;br /&gt;      fixtures File.basename(f, '.yml')&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  ..&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;and in your tests use it as follows:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class FooTest &lt; Test::Unit::TestCase&lt;br /&gt;  all_fixtures&lt;br /&gt;&lt;br /&gt;  ..&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Happy testing!</description>
      <pubDate>Fri, 18 Jan 2008 19:01:16 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5007</guid>
      <author>remvee (Remco van 't Veer)</author>
    </item>
    <item>
      <title>response caching in camping</title>
      <link>http://snippets.dzone.com/posts/show/4988</link>
      <description>A basic implementation of response caching in camping.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Camping.goes :MyCampingApp&lt;br /&gt;&lt;br /&gt;module MyCampingApp&lt;br /&gt;  module Controller&lt;br /&gt;    class View &lt; R '/'&lt;br /&gt;      def get&lt;br /&gt;        cache('root') do&lt;br /&gt;          'Expensive operation!'&lt;br /&gt;        end&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def flush(id)&lt;br /&gt;    f = File.dirname(__FILE__) + "/cache/#{id}"&lt;br /&gt;    File.delete(f) if File.exists?(f)&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def cache(id, timeout = 1.hour)&lt;br /&gt;    f = File.dirname(__FILE__) + "/cache/#{id}"&lt;br /&gt;    &lt;br /&gt;    if File.exists?(f) &amp;&amp; (Time.now - File.stat(f).mtime) &lt; timeout&lt;br /&gt;      File.read(f)&lt;br /&gt;    else&lt;br /&gt;      r = yield&lt;br /&gt;      open(f, 'w'){|wr| wr.write(r)}&lt;br /&gt;      r&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  def self.create&lt;br /&gt;    cache_dir = File.dirname(__FILE__) + "/cache"&lt;br /&gt;    Dir.mkdir(cache_dir) unless File.directory?(cache_dir)&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Wed, 16 Jan 2008 13:27:23 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4988</guid>
      <author>remvee (Remco van 't Veer)</author>
    </item>
    <item>
      <title>avoid web caching</title>
      <link>http://snippets.dzone.com/posts/show/2708</link>
      <description>&lt;code&gt;&lt;br /&gt;// Set to expire far in the past.&lt;br /&gt;response.setHeader("Expires", "Sat, 6 May 1995 12:00:00 GMT");&lt;br /&gt;// Set standard HTTP/1.1 no-cache headers.&lt;br /&gt;response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");&lt;br /&gt;// Set IE extended HTTP/1.1 no-cache headers (use addHeader).&lt;br /&gt;response.addHeader("Cache-Control", "post-check=0, pre-check=0");&lt;br /&gt;// Set standard HTTP/1.0 no-cache header.&lt;br /&gt;response.setHeader("Pragma", "no-cache");&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Mon, 25 Sep 2006 00:28:46 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2708</guid>
      <author>remvee (Remco van 't Veer)</author>
    </item>
    <item>
      <title>Disable protected attributes in ActiveRecordHelper forms</title>
      <link>http://snippets.dzone.com/posts/show/2489</link>
      <description>To make the form method in ActiveRecordHelper disable protected attribute, place the following in your application_help.rb:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;def attr_protected?(record, column)&lt;br /&gt;  o = instance_variable_get("@#{record}")&lt;br /&gt;  o &amp;&amp; o.class.protected_attributes &amp;&amp;&lt;br /&gt;      o.class.protected_attributes.include?(column.name.to_sym)&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def default_input_block&lt;br /&gt;  Proc.new { |record, column|&lt;br /&gt;    options = attr_protected?(record, column) ? {:disabled =&gt; true} : {}&lt;br /&gt;    &lt;&lt;-"end_html" &lt;br /&gt;      &lt;p&gt;&lt;br /&gt;        &lt;label for="#{record}_#{column.name}"&gt;#{column.human_name}&lt;/label&gt;&lt;br /&gt;        &lt;br /&gt;&lt;br /&gt;        #{input(record, column.name, options)}&lt;br /&gt;      &lt;/p&gt;&lt;br /&gt;    end_html&lt;br /&gt;  }&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And mark some attributes protected, for example:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Item &lt; ActiveRecord::Base&lt;br /&gt;  attr_protected :created_at&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The created_at attribute will be rendered but won't be editable.  This will work for "dynamic scaffolds" too!</description>
      <pubDate>Mon, 28 Aug 2006 20:48:51 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2489</guid>
      <author>remvee (Remco van 't Veer)</author>
    </item>
    <item>
      <title>time based cache</title>
      <link>http://snippets.dzone.com/posts/show/2360</link>
      <description>A simple time based cache build around a map store.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import java.util.Map;&lt;br /&gt;import java.util.WeakHashMap;&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Simple time-based cache.&lt;br /&gt; */&lt;br /&gt;public class SimpleCache {&lt;br /&gt;	private long maxAge;&lt;br /&gt;	private Map store;&lt;br /&gt;&lt;br /&gt;	/**&lt;br /&gt;	 * Instanciate a cache with max age of 1 hour and a WeakHashMap as store.&lt;br /&gt;	 * @see java.util.WeakHashMap&lt;br /&gt;	 */&lt;br /&gt;	public SimpleCache() {&lt;br /&gt;		this.maxAge = 1000 * 60 * 60;&lt;br /&gt;		this.store = new WeakHashMap();&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	/**&lt;br /&gt;	 * @param maxAge maximum age of an entry in milliseconds&lt;br /&gt;	 * @param store map to hold entries&lt;br /&gt;	 */&lt;br /&gt;	public SimpleCache(long maxAge, Map store) {&lt;br /&gt;		this.maxAge = maxAge;&lt;br /&gt;		this.store = store;&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	/**&lt;br /&gt;	 * Cache an object.&lt;br /&gt;	 * @param key unique identifier to retrieve object&lt;br /&gt;	 * @param value object to cache&lt;br /&gt;	 */&lt;br /&gt;	public void put(Object key, Object value) {&lt;br /&gt;		store.put(key, new Item(value));&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	/**&lt;br /&gt;	 * Fetch an object.&lt;br /&gt;	 * @param key unique identifier to retrieve object&lt;br /&gt;	 * @return an object or null in case it isn't stored or it expired&lt;br /&gt;	 */&lt;br /&gt;	public Object get(Object key) {&lt;br /&gt;		Item item = getItem(key);&lt;br /&gt;		return item == null ? null : item.payload;&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	/**&lt;br /&gt;	 * Fetch an object or store and return output of callback.&lt;br /&gt;	 * @param key unique identifier to retrieve object&lt;br /&gt;	 * @param block code executed when object not in cache&lt;br /&gt;	 * @return an object&lt;br /&gt;	 */&lt;br /&gt;	public synchronized Object get(Object key, Callback block) {&lt;br /&gt;		Item item = getItem(key);&lt;br /&gt;		if (item == null) {&lt;br /&gt;			Object value = block.execute();&lt;br /&gt;			item = new Item(value);&lt;br /&gt;			store.put(key, item);&lt;br /&gt;		}&lt;br /&gt;		return item.payload;&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	/**&lt;br /&gt;	 * Remove an object from cache.&lt;br /&gt;	 * @param key unique identifier to retrieve object&lt;br /&gt;	 */&lt;br /&gt;	public void remove(Object key) {&lt;br /&gt;		store.remove(key);&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	/**&lt;br /&gt;	 * Get an item, if it expired remove it from cache and return null.&lt;br /&gt;	 * @param key unique identifier to retrieve object&lt;br /&gt;	 * @return an item or null&lt;br /&gt;	 */&lt;br /&gt;	private Item getItem(Object key) {&lt;br /&gt;		Item item = (Item) store.get(key);&lt;br /&gt;		if (item == null) {&lt;br /&gt;			return null;&lt;br /&gt;		}&lt;br /&gt;		if (System.currentTimeMillis() - item.birth &gt; maxAge) {&lt;br /&gt;			store.remove(key);&lt;br /&gt;			return null;&lt;br /&gt;		}&lt;br /&gt;		return item;		&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	/**&lt;br /&gt;	 * Value container.&lt;br /&gt;	 */&lt;br /&gt;	private static class Item {&lt;br /&gt;		long birth;&lt;br /&gt;		Object payload;&lt;br /&gt;		Item(Object payload) {&lt;br /&gt;			this.birth = System.currentTimeMillis();&lt;br /&gt;			this.payload = payload;&lt;br /&gt;		}&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	/**&lt;br /&gt;	 * A visitor interface.&lt;br /&gt;	 */&lt;br /&gt;	public static interface Callback {&lt;br /&gt;		Object execute();&lt;br /&gt;	}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And a couple of junit tests:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import java.util.HashMap;&lt;br /&gt;&lt;br /&gt;import junit.framework.TestCase;&lt;br /&gt;&lt;br /&gt;public class SimpleCacheTest extends TestCase {&lt;br /&gt;	public void testPutGet () {&lt;br /&gt;		SimpleCache c = new SimpleCache(Long.MAX_VALUE, new HashMap());&lt;br /&gt;		c.put("key1", "value1");&lt;br /&gt;		assertEquals("value1", c.get("key1"));&lt;br /&gt;		c.put("key1", "value1.0");&lt;br /&gt;		assertEquals("value1.0", c.get("key1"));&lt;br /&gt;		c.put("key2", "value2");&lt;br /&gt;		assertEquals("value2", c.get("key2"));&lt;br /&gt;		assertEquals("value1.0", c.get("key1"));&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	public void testMaxAge () throws InterruptedException {&lt;br /&gt;		SimpleCache c = new SimpleCache(1000, new HashMap());&lt;br /&gt;		c.put("key1", "value1");&lt;br /&gt;		assertEquals("value1", c.get("key1"));&lt;br /&gt;		Thread.sleep(1500);&lt;br /&gt;		assertNull(c.get("key1"));&lt;br /&gt;		&lt;br /&gt;		c.put("key2", "value2");&lt;br /&gt;		Thread.sleep(750);&lt;br /&gt;		c.put("key3", "value3");&lt;br /&gt;		Thread.sleep(750);&lt;br /&gt;		assertNull(c.get("key2"));&lt;br /&gt;		assertNotNull(c.get("key3"));&lt;br /&gt;		Thread.sleep(750);&lt;br /&gt;		assertNull(c.get("key3"));&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	public void testRemove () {&lt;br /&gt;		SimpleCache c = new SimpleCache(Long.MAX_VALUE, new HashMap());&lt;br /&gt;		c.remove("key");&lt;br /&gt;		assertNull(c.get("key"));&lt;br /&gt;		c.put("key", "value");&lt;br /&gt;		assertNotNull(c.get("key"));&lt;br /&gt;		c.remove("key");&lt;br /&gt;		assertNull(c.get("key"));&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	public void testCallBack () {&lt;br /&gt;		SimpleCache c = new SimpleCache(Long.MAX_VALUE, new HashMap());&lt;br /&gt;		assertEquals("value1", c.get("key1", new SimpleCache.Callback() {&lt;br /&gt;			public Object execute() {&lt;br /&gt;				return "value1";&lt;br /&gt;			}&lt;br /&gt;		}));&lt;br /&gt;		assertEquals("value1", c.get("key1"));&lt;br /&gt;		&lt;br /&gt;		// again with a new callback (value)&lt;br /&gt;		c.get("key1", new SimpleCache.Callback() {&lt;br /&gt;			public Object execute() {&lt;br /&gt;				return "value2";&lt;br /&gt;			}&lt;br /&gt;		});&lt;br /&gt;		assertEquals("value1", c.get("key1"));&lt;br /&gt;	}&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 03 Aug 2006 18:27:52 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2360</guid>
      <author>remvee (Remco van 't Veer)</author>
    </item>
    <item>
      <title>give focus to first input field or textarea on page</title>
      <link>http://snippets.dzone.com/posts/show/2192</link>
      <description>Place the following in your application.js file and make sure your layout includes "javascript_include_tag :defaults".&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Event.observe(window, 'load', function() {&lt;br /&gt;  var e = $A(document.getElementsByTagName('*')).find(function(e) {&lt;br /&gt;    return (e.tagName.toUpperCase() == 'INPUT' &amp;&amp; (e.type == 'text' || e.type == 'password'))&lt;br /&gt;        || e.tagName.toUpperCase() == 'TEXTAREA' || e.tagName.toUpperCase() == 'SELECT';&lt;br /&gt;  });&lt;br /&gt;  if (e) e.focus();&lt;br /&gt;});&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 15 Jun 2006 12:05:55 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2192</guid>
      <author>remvee (Remco van 't Veer)</author>
    </item>
    <item>
      <title>non persistent ActiveRecord</title>
      <link>http://snippets.dzone.com/posts/show/1963</link>
      <description>&lt;code&gt;&lt;br /&gt;# = ActiveForm - non persistent ActiveRecord&lt;br /&gt;#&lt;br /&gt;# Simple base class to make AR objects without a corresponding database&lt;br /&gt;# table.  These objects can still use AR validations but can't be saved&lt;br /&gt;# to the database.  Use the +valid?+ method to validate.&lt;br /&gt;#&lt;br /&gt;# == Example&lt;br /&gt;#&lt;br /&gt;#   class FeedbackForm &lt; ActiveForm&lt;br /&gt;#     column :email&lt;br /&gt;#     column :message&lt;br /&gt;#     validates_presence_of :email, :message&lt;br /&gt;#   end&lt;br /&gt;#&lt;br /&gt;class ActiveForm &lt; ActiveRecord::Base&lt;br /&gt;  def self.columns() @columns ||= []; end # :nodoc:&lt;br /&gt;  &lt;br /&gt;  # Define an attribute, takes the same arguments as&lt;br /&gt;  # ActiveRecord::ConnectionAdapters::Column.new only in a&lt;br /&gt;  # slightly different order.&lt;br /&gt;  def self.column(name, sql_type = nil, default = nil, null = true)&lt;br /&gt;    columns &lt;&lt; ActiveRecord::ConnectionAdapters::Column.new(&lt;br /&gt;        name.to_s, default, sql_type.to_s, null)&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 27 Apr 2006 11:52:06 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1963</guid>
      <author>remvee (Remco van 't Veer)</author>
    </item>
  </channel>
</rss>
