mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Initial
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
10
actionpack/lib/action_controller/support/clean_logger.rb
Normal file
10
actionpack/lib/action_controller/support/clean_logger.rb
Normal 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
|
||||
@@ -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
|
||||
78
actionpack/lib/action_controller/support/inflector.rb
Normal file
78
actionpack/lib/action_controller/support/inflector.rb
Normal 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
|
||||
Reference in New Issue
Block a user