git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
David Heinemeier Hansson
2004-11-24 01:04:44 +00:00
commit db045dbbf6
296 changed files with 30881 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
# Extends the class object with class and instance accessors for class attributes,
# just like the native attr* accessors for instance attributes.
class Class # :nodoc:
def cattr_reader(*syms)
syms.each do |sym|
class_eval <<-EOS
if ! defined? @@#{sym.id2name}
@@#{sym.id2name} = nil
end
def self.#{sym.id2name}
@@#{sym}
end
def #{sym.id2name}
@@#{sym}
end
def call_#{sym.id2name}
case @@#{sym.id2name}
when Symbol then send(@@#{sym})
when Proc then @@#{sym}.call(self)
when String then @@#{sym}
else nil
end
end
EOS
end
end
def cattr_writer(*syms)
syms.each do |sym|
class_eval <<-EOS
if ! defined? @@#{sym.id2name}
@@#{sym.id2name} = nil
end
def self.#{sym.id2name}=(obj)
@@#{sym.id2name} = obj
end
def self.set_#{sym.id2name}(obj)
@@#{sym.id2name} = obj
end
def #{sym.id2name}=(obj)
@@#{sym} = obj
end
EOS
end
end
def cattr_accessor(*syms)
cattr_reader(*syms)
cattr_writer(*syms)
end
end

View File

@@ -0,0 +1,37 @@
# Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
# their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
# to, for example, an array without those additions being shared with either their parent, siblings, or
# children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
module ClassInheritableAttributes # :nodoc:
def self.append_features(base)
super
base.extend(ClassMethods)
end
module ClassMethods # :nodoc:
@@classes ||= {}
def inheritable_attributes
@@classes[self] ||= {}
end
def write_inheritable_attribute(key, value)
inheritable_attributes[key] = value
end
def write_inheritable_array(key, elements)
write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
end
def read_inheritable_attribute(key)
inheritable_attributes[key]
end
private
def inherited(child)
@@classes[child] = inheritable_attributes.dup
end
end
end

View File

@@ -0,0 +1,10 @@
require 'logger'
class Logger #:nodoc:
private
remove_const "Format"
Format = "%s\n"
def format_message(severity, timestamp, msg, progname)
Format % [msg]
end
end

View File

@@ -0,0 +1,121 @@
CGI.module_eval { remove_const "Cookie" }
class CGI #:nodoc:
# This is a cookie class that fixes the performance problems with the default one that ships with 1.8.1 and below.
# It replaces the inheritance on SimpleDelegator with DelegateClass(Array) following the suggestion from Matz on
# http://groups.google.com/groups?th=e3a4e68ba042f842&seekm=c3sioe%241qvm%241%40news.cybercity.dk#link14
class Cookie < DelegateClass(Array)
# Create a new CGI::Cookie object.
#
# The contents of the cookie can be specified as a +name+ and one
# or more +value+ arguments. Alternatively, the contents can
# be specified as a single hash argument. The possible keywords of
# this hash are as follows:
#
# name:: the name of the cookie. Required.
# value:: the cookie's value or list of values.
# path:: the path for which this cookie applies. Defaults to the
# base directory of the CGI script.
# domain:: the domain for which this cookie applies.
# expires:: the time at which this cookie expires, as a +Time+ object.
# secure:: whether this cookie is a secure cookie or not (default to
# false). Secure cookies are only transmitted to HTTPS
# servers.
#
# These keywords correspond to attributes of the cookie object.
def initialize(name = "", *value)
options = if name.kind_of?(String)
{ "name" => name, "value" => value }
else
name
end
unless options.has_key?("name")
raise ArgumentError, "`name' required"
end
@name = options["name"]
@value = Array(options["value"])
# simple support for IE
if options["path"]
@path = options["path"]
else
%r|^(.*/)|.match(ENV["SCRIPT_NAME"])
@path = ($1 or "")
end
@domain = options["domain"]
@expires = options["expires"]
@secure = options["secure"] == true ? true : false
super(@value)
end
def __setobj__(obj)
@_dc_obj = obj
end
attr_accessor("name", "value", "path", "domain", "expires")
attr_reader("secure")
# Set whether the Cookie is a secure cookie or not.
#
# +val+ must be a boolean.
def secure=(val)
@secure = val if val == true or val == false
@secure
end
# Convert the Cookie to its string representation.
def to_s
buf = ""
buf += @name + '='
if @value.kind_of?(String)
buf += CGI::escape(@value)
else
buf += @value.collect{|v| CGI::escape(v) }.join("&")
end
if @domain
buf += '; domain=' + @domain
end
if @path
buf += '; path=' + @path
end
if @expires
buf += '; expires=' + CGI::rfc1123_date(@expires)
end
if @secure == true
buf += '; secure'
end
buf
end
# Parse a raw cookie string into a hash of cookie-name=>Cookie
# pairs.
#
# cookies = CGI::Cookie::parse("raw_cookie_string")
# # { "name1" => cookie1, "name2" => cookie2, ... }
#
def self.parse(raw_cookie)
cookies = Hash.new([])
return cookies unless raw_cookie
raw_cookie.split(/; /).each do |pairs|
name, values = pairs.split('=',2)
next unless name and values
name = CGI::unescape(name)
values ||= ""
values = values.split('&').collect{|v| CGI::unescape(v) }
unless cookies.has_key?(name)
cookies[name] = new({ "name" => name, "value" => values })
end
end
cookies
end
end # class Cookie
end

View File

@@ -0,0 +1,78 @@
# The Inflector transforms words from singular to plural, class names to table names, modulized class names to ones without,
# and class names to foreign keys.
module Inflector
extend self
def pluralize(word)
result = word.dup
plural_rules.each do |(rule, replacement)|
break if result.gsub!(rule, replacement)
end
return result
end
def singularize(word)
result = word.dup
singular_rules.each do |(rule, replacement)|
break if result.gsub!(rule, replacement)
end
return result
end
def camelize(lower_case_and_underscored_word)
lower_case_and_underscored_word.gsub(/(^|_)(.)/){$2.upcase}
end
def underscore(camel_cased_word)
camel_cased_word.gsub(/([A-Z]+)([A-Z])/,'\1_\2').gsub(/([a-z])([A-Z])/,'\1_\2').downcase
end
def demodulize(class_name_in_module)
class_name_in_module.gsub(/^.*::/, '')
end
def tableize(class_name)
pluralize(underscore(class_name))
end
def classify(table_name)
camelize(singularize(table_name))
end
def foreign_key(class_name, separate_class_name_and_id_with_underscore = true)
Inflector.underscore(Inflector.demodulize(class_name)) +
(separate_class_name_and_id_with_underscore ? "_id" : "id")
end
private
def plural_rules #:doc:
[
[/(x|ch|ss)$/, '\1es'], # search, switch, fix, box, process, address
[/([^aeiouy]|qu)y$/, '\1ies'], # query, ability, agency
[/(?:([^f])fe|([lr])f)$/, '\1\2ves'], # half, safe, wife
[/sis$/, 'ses'], # basis, diagnosis
[/([ti])um$/, '\1a'], # datum, medium
[/person$/, 'people'], # person, salesperson
[/man$/, 'men'], # man, woman, spokesman
[/child$/, 'children'], # child
[/s$/, 's'], # no change (compatibility)
[/$/, 's']
]
end
def singular_rules #:doc:
[
[/(x|ch|ss)es$/, '\1'],
[/([^aeiouy]|qu)ies$/, '\1y'],
[/([lr])ves$/, '\1f'],
[/([^f])ves$/, '\1fe'],
[/(analy|ba|diagno|parenthe|progno|synop|the)ses$/, '\1sis'],
[/([ti])a$/, '\1um'],
[/people$/, 'person'],
[/men$/, 'man'],
[/status$/, 'status'],
[/children$/, 'child'],
[/s$/, '']
]
end
end