元编程
2018-02-24 16:10 更新
-
避免无谓的元编程。
-
写一个函数库时不要使核心类混乱(不要使用 monkey patch)。
-
倾向使用区块形式的
class_eval
而不是字符串插值(string-interpolated)的形式。-
当你使用字符串插值形式时,总是提供
__FILE__
及__LINE__
,使你的 backtrace 看起来有意义:class_eval "def use_relative_model_naming?; true; end", __FILE__, __LINE__
- 倾向使用
define_method
而不是class_eval{ def ... }
-
-
当使用
class_eval
(或其它的eval
)搭配字符串插值时,添加一个注解区块,来演示如果做了插值的样子(我从 Rails 代码学来的一个实践):# activesupport/lib/active_support/core_ext/string/output_safety.rb UNSAFE_STRING_METHODS.each do |unsafe_method| if 'String'.respond_to?(unsafe_method) class_eval <<-EOT, __FILE__, __LINE__ + 1 def #{unsafe_method}(*args, &block) # def capitalize(*args, &block) to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block) end # end def #{unsafe_method}!(*args) # def capitalize!(*args) @dirty = true # @dirty = true super # super end # end EOT end end
-
元编程避免使用
method_missing
。会让 Backtraces 变得很凌乱;行为没有列在#methods
里;拼错的方法调用可能默默的工作(nukes.launch_state = false
)。考虑使用 delegation, proxy, 或是define_method
来取代。如果你必须使用method_missing
,- 确保 也定义了
respond_to_missing?
- 仅捕捉字首定义良好的方法,像是
find_by_*
——让你的代码愈肯定(assertive) 愈好。 - 在语句的最后调用
super
-
delegate 到确定的、非魔法方法中:
# 差 def method_missing?(meth, *args, &block) if /^find_by_(?<prop>.*)/ =~ meth # ... lots of code to do a find_by else super end end # 好 def method_missing?(meth, *args, &block) if /^find_by_(?<prop>.*)/ =~ meth find_by(prop, *args, &block) else super end end # 最好的方式,可能是每个可找到的属性被声明后,使用 define_method。
- 确保 也定义了
以上内容是否对您有帮助:
← 百分比字面
更多建议: