class Mongrel2::Table
The Mongrel2
Table
class. Instances of this class provide a case-insensitive hash-like object that can store multiple values per key.
headers = Mongrel2::Table.new headers['User-Agent'] = 'PornBrowser 1.1.5' headers['user-agent'] # => 'PornBrowser 1.1.5' headers[:user_agent] # => 'PornBrowser 1.1.5' headers.user_agent # => 'PornBrowser 1.1.5'
Author/s¶ ↑
-
Michael Granger <ged@FaerieMUD.org>
-
Mahlon E. Smith <mahlon@martini.nu>
Constants
- KEYED_METHODS
Methods that understand case-insensitive keys
- NON_DELEGATED_METHODS
Method to not delegate to the inner hash
Public Class Methods
Auto-generate methods which call the given delegate
after normalizing their first argument via normalize_key
# File lib/mongrel2/table.rb, line 39 def self::def_normalized_delegators( delegate, *syms ) syms.each do |methodname| define_method( methodname ) do |key, *args| nkey = normalize_key( key ) instance_variable_get( delegate ). __send__( methodname, nkey, *args ) end end end
Create a new Mongrel2::Table
using the given hash
for initial values.
# File lib/mongrel2/table.rb, line 56 def initialize( initial_values={} ) @hash = {} initial_values.each {|k,v| self.append(k => v) } end
Public Instance Methods
Append the keys and values in the given hash
to the table, transforming each value into an array if there was an existing value for the same key.
# File lib/mongrel2/table.rb, line 86 def append( hash ) self.merge!( hash ) do |key,origval,newval| [ origval, newval ].flatten end end
Enumerator for iterating over the table contents, yielding each as an RFC822 header.
# File lib/mongrel2/table.rb, line 107 def each_header( &block ) enum = Enumerator.new do |yielder| @hash.each do |header, value| Array( value ).each do |val| yielder.yield( normalize_header(header), val.to_s ) end end end if block return enum.each( &block ) else return enum end end
Overridden to freeze the inner hash as well.
# File lib/mongrel2/table.rb, line 169 def freeze super @hash.freeze end
Return a human-readable representation of the object suitable for debugging.
# File lib/mongrel2/table.rb, line 159 def inspect return "#<%p:%#x %p>" % [ self.class, self.object_id * 2, @hash ] end
Return a new table which is the result of merging the receiver with other_table
in the same fashion as Hash#merge. If the optional merge_callback
block is provided, it is called whenever there is a key collision between the two.
# File lib/mongrel2/table.rb, line 143 def merge( other_table, &merge_callback ) # :yields: key, original_value, new_value other = self.dup other.merge!( other_table, &merge_callback ) return other end
Merge other_table
into the receiver.
# File lib/mongrel2/table.rb, line 132 def merge!( other_table, &merge_callback ) nhash = normalize_hash( other_table.to_hash ) @hash.merge!( nhash, &merge_callback ) end
Return the Table
as a hash.
# File lib/mongrel2/table.rb, line 125 def to_h @hash.dup end
Return the Table
as RFC822 headers in a String
# File lib/mongrel2/table.rb, line 94 def to_s @hash.collect do |header,value| Array( value ).collect {|val| "%s: %s" % [ normalize_header( header ), val ] } end.flatten.sort.join( "\r\n" ) + "\r\n" end
Return an array containing the values associated with the given keys.
# File lib/mongrel2/table.rb, line 153 def values_at( *keys ) @hash.values_at( *(keys.collect {|k| normalize_key(k)}) ) end
Protected Instance Methods
Create a Proc that will act as a getter for the given key
# File lib/mongrel2/table.rb, line 207 def make_getter( key ) return Proc.new { self[key] } end
Create a Proc that will act as a setter for the given key
# File lib/mongrel2/table.rb, line 201 def make_setter( key ) return Proc.new {|new_value| self[ key ] = new_value } end
Proxy method: handle getting/setting headers via methods instead of the index operator.
# File lib/mongrel2/table.rb, line 181 def method_missing( sym, *args ) # work magic return super unless sym.to_s =~ /^([a-z]\w+)(=)?$/ # If it's an assignment, the (=)? will have matched key, assignment = $1, $2 method_body = nil if assignment method_body = self.make_setter( key ) else method_body = self.make_getter( key ) end self.class.send( :define_method, sym, &method_body ) return self.method( sym ).call( *args ) end
Private Instance Methods
Recursively copying the specified obj
and return the result.
# File lib/mongrel2/table.rb, line 241 def deep_copy( obj ) # Handle mocks during testing return obj if obj.class.name == 'RSpec::Mocks::Mock' return case obj when NilClass, Numeric, TrueClass, FalseClass, Symbol obj when Array obj.map {|o| deep_copy(o) } when Hash newhash = {} obj.each do |k,v| newhash[ deep_copy(k) ] = deep_copy( v ) end newhash else obj.clone end end
Return a copy of hash
with all of its keys normalized by normalize_key
.
# File lib/mongrel2/table.rb, line 217 def normalize_hash( hash ) hash = hash.dup hash.keys.each do |key| nkey = normalize_key( key ) hash[ nkey ] = hash.delete( key ) if key != nkey end return hash end
Return the given key as an RFC822-style header label
# File lib/mongrel2/table.rb, line 235 def normalize_header( key ) key.to_s.split( '_' ).collect {|part| part.capitalize }.join( '-' ) end
Normalize the given key to equivalence
# File lib/mongrel2/table.rb, line 229 def normalize_key( key ) key.to_s.downcase.gsub('-', '_').to_sym end