Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
9fa329b7
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
9fa329b7
编写于
11月 14, 2011
作者:
J
José Valim
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Speed up attribute invocation by checking if both name and calls are compilable.
上级
2088f1b3
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
34 addition
and
29 deletion
+34
-29
activemodel/lib/active_model/attribute_methods.rb
activemodel/lib/active_model/attribute_methods.rb
+32
-27
activerecord/lib/active_record/attribute_methods/read.rb
activerecord/lib/active_record/attribute_methods/read.rb
+1
-1
activerecord/lib/active_record/attribute_methods/write.rb
activerecord/lib/active_record/attribute_methods/write.rb
+1
-1
未找到文件。
activemodel/lib/active_model/attribute_methods.rb
浏览文件 @
9fa329b7
...
...
@@ -57,7 +57,8 @@ class MissingAttributeError < NoMethodError
module
AttributeMethods
extend
ActiveSupport
::
Concern
COMPILABLE_REGEXP
=
/\A[a-zA-Z_]\w*[!?=]?\z/
NAME_COMPILABLE_REGEXP
=
/\A[a-zA-Z_]\w*[!?=]?\z/
CALL_COMPILABLE_REGEXP
=
/\A[a-zA-Z_]\w*[!?]?\z/
included
do
class_attribute
:attribute_method_matchers
,
:instance_writer
=>
false
...
...
@@ -112,7 +113,7 @@ def define_attr_method(name, value=nil, &block)
# If we can compile the method name, do it. Otherwise use define_method.
# This is an important *optimization*, please don't change it. define_method
# has slower dispatch and consumes more memory.
if
name
=~
COMPILABLE_REGEXP
if
name
=~
NAME_
COMPILABLE_REGEXP
sing
.
class_eval
<<-
RUBY
,
__FILE__
,
__LINE__
+
1
def
#{
name
}
;
#{
value
.
nil?
?
'nil'
:
value
.
to_s
.
inspect
}
; end
RUBY
...
...
@@ -240,18 +241,7 @@ def alias_attribute(new_name, old_name)
attribute_method_matchers
.
each
do
|
matcher
|
matcher_new
=
matcher
.
method_name
(
new_name
).
to_s
matcher_old
=
matcher
.
method_name
(
old_name
).
to_s
if
matcher_new
=~
COMPILABLE_REGEXP
&&
matcher_old
=~
COMPILABLE_REGEXP
module_eval
<<-
RUBY
,
__FILE__
,
__LINE__
+
1
def
#{
matcher_new
}
(*args)
send(:
#{
matcher_old
}
, *args)
end
RUBY
else
define_method
(
matcher_new
)
do
|*
args
|
send
(
matcher_old
,
*
args
)
end
end
define_optimized_call
self
,
matcher_new
,
matcher_old
end
end
...
...
@@ -293,17 +283,7 @@ def define_attribute_method(attr_name)
if
respond_to?
(
generate_method
)
send
(
generate_method
,
attr_name
)
else
if
method_name
=~
COMPILABLE_REGEXP
defn
=
"def
#{
method_name
}
(*args)"
else
defn
=
"define_method(:'
#{
method_name
}
') do |*args|"
end
generated_attribute_methods
.
module_eval
<<-
RUBY
,
__FILE__
,
__LINE__
+
1
#{
defn
}
send(:
#{
matcher
.
method_missing_target
}
, '
#{
attr_name
}
', *args)
end
RUBY
define_optimized_call
generated_attribute_methods
,
method_name
,
matcher
.
method_missing_target
,
attr_name
.
to_s
end
end
end
...
...
@@ -342,11 +322,11 @@ def instance_method_already_implemented?(method_name)
# used to alleviate the GC, which ultimately also speeds up the app
# significantly (in our case our test suite finishes 10% faster with
# this cache).
def
attribute_method_matchers_cache
def
attribute_method_matchers_cache
#:nodoc:
@attribute_method_matchers_cache
||=
{}
end
def
attribute_method_matcher
(
method_name
)
def
attribute_method_matcher
(
method_name
)
#:nodoc:
if
attribute_method_matchers_cache
.
key?
(
method_name
)
attribute_method_matchers_cache
[
method_name
]
else
...
...
@@ -359,6 +339,31 @@ def attribute_method_matcher(method_name)
end
end
# Define a method `name` in `mod` that dispatches to `send`
# using the given `extra` args. This fallbacks `define_method`
# and `send` if the given names cannot be compiled.
def
define_optimized_call
(
mod
,
name
,
send
,
*
extra
)
#:nodoc:
if
name
=~
NAME_COMPILABLE_REGEXP
defn
=
"def
#{
name
}
(*args)"
else
defn
=
"define_method(:'
#{
name
}
') do |*args|"
end
extra
=
(
extra
.
map
(
&
:inspect
)
<<
"*args"
).
join
(
", "
)
if
send
=~
CALL_COMPILABLE_REGEXP
target
=
"
#{
send
}
(
#{
extra
}
)"
else
target
=
"send(:'
#{
send
}
',
#{
extra
}
)"
end
mod
.
module_eval
<<-
RUBY
,
__FILE__
,
__LINE__
+
1
#{
defn
}
#{
target
}
end
RUBY
end
class
AttributeMethodMatcher
attr_reader
:prefix
,
:suffix
,
:method_missing_target
...
...
activerecord/lib/active_record/attribute_methods/read.rb
浏览文件 @
9fa329b7
...
...
@@ -77,7 +77,7 @@ def define_read_method(method_name, attr_name, column)
#
# The second, slower, branch is necessary to support instances where the database
# returns columns with extra stuff in (like 'my_column(omg)').
if
method_name
=~
ActiveModel
::
AttributeMethods
::
COMPILABLE_REGEXP
if
method_name
=~
ActiveModel
::
AttributeMethods
::
NAME_
COMPILABLE_REGEXP
generated_attribute_methods
.
module_eval
<<-
STR
,
__FILE__
,
__LINE__
def _
#{
method_name
}
#{
access_code
}
...
...
activerecord/lib/active_record/attribute_methods/write.rb
浏览文件 @
9fa329b7
...
...
@@ -10,7 +10,7 @@ module Write
module
ClassMethods
protected
def
define_method_attribute
=
(
attr_name
)
if
attr_name
=~
ActiveModel
::
AttributeMethods
::
COMPILABLE_REGEXP
if
attr_name
=~
ActiveModel
::
AttributeMethods
::
NAME_
COMPILABLE_REGEXP
generated_attribute_methods
.
module_eval
(
"def
#{
attr_name
}
=(new_value); write_attribute('
#{
attr_name
}
', new_value); end"
,
__FILE__
,
__LINE__
)
else
generated_attribute_methods
.
send
(
:define_method
,
"
#{
attr_name
}
="
)
do
|
new_value
|
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录