Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

use fetch rather than both Hash#key? and Hash#[]

  • Loading branch information...
commit 0581c1a95c7ea9df88d5fd975ada40b0d8540d46 1 parent 148f849
@tenderlove tenderlove authored
Showing with 51 additions and 49 deletions.
  1. +51 −49 activerecord/lib/active_record/attribute_methods/read.rb
View
100 activerecord/lib/active_record/attribute_methods/read.rb
@@ -58,66 +58,68 @@ def type_cast_attribute(attr_name, attributes, cache = {}) #:nodoc:
end
protected
- # We want to generate the methods via module_eval rather than define_method,
- # because define_method is slower on dispatch and uses more memory (because it
- # creates a closure).
- #
- # But sometimes the database might return columns with characters that are not
- # allowed in normal method names (like 'my_column(omg)'. So to work around this
- # we first define with the __temp__ identifier, and then use alias method to
- # rename it to what we want.
- def define_method_attribute(attr_name)
- cast_code = attribute_cast_code(attr_name)
-
- generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
- def __temp__
- #{internal_attribute_access_code(attr_name, cast_code)}
- end
- alias_method '#{attr_name}', :__temp__
- undef_method :__temp__
- STR
-
- generated_external_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
- def __temp__(v, attributes, attributes_cache, attr_name)
- #{external_attribute_access_code(attr_name, cast_code)}
- end
- alias_method '#{attr_name}', :__temp__
- undef_method :__temp__
- STR
- end
+ # We want to generate the methods via module_eval rather than define_method,
+ # because define_method is slower on dispatch and uses more memory (because it
+ # creates a closure).
+ #
+ # But sometimes the database might return columns with characters that are not
+ # allowed in normal method names (like 'my_column(omg)'. So to work around this
+ # we first define with the __temp__ identifier, and then use alias method to
+ # rename it to what we want.
+ def define_method_attribute(attr_name)
+ cast_code = attribute_cast_code(attr_name)
+
+ generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
+ def __temp__
+ #{internal_attribute_access_code(attr_name, cast_code)}
+ end
+ alias_method '#{attr_name}', :__temp__
+ undef_method :__temp__
+ STR
- private
- def cacheable_column?(column)
- attribute_types_cached_by_default.include?(column.type)
- end
+ generated_external_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
+ def __temp__(v, attributes, attributes_cache, attr_name)
+ #{external_attribute_access_code(attr_name, cast_code)}
+ end
+ alias_method '#{attr_name}', :__temp__
+ undef_method :__temp__
+ STR
+ end
- def internal_attribute_access_code(attr_name, cast_code)
- access_code = "(v=@attributes[attr_name]) && #{cast_code}"
+ private
+ def cacheable_column?(column)
+ attribute_types_cached_by_default.include?(column.type)
+ end
- unless attr_name == primary_key
- access_code.insert(0, "missing_attribute(attr_name, caller) unless @attributes.has_key?(attr_name); ")
- end
+ def internal_attribute_access_code(attr_name, cast_code)
+ if attr_name == primary_key
+ access_code = "v = @attributes[attr_name];"
+ else
+ access_code = "v = @attributes.fetch(attr_name) { missing_attribute(attr_name, caller) };"
+ end
- if cache_attribute?(attr_name)
- access_code = "@attributes_cache[attr_name] ||= (#{access_code})"
- end
+ access_code << "v && #{cast_code};"
- "attr_name = '#{attr_name}'; #{access_code}"
+ if cache_attribute?(attr_name)
+ access_code = "@attributes_cache[attr_name] ||= (#{access_code})"
end
- def external_attribute_access_code(attr_name, cast_code)
- access_code = "v && #{cast_code}"
+ "attr_name = '#{attr_name}'; #{access_code}"
+ end
- if cache_attribute?(attr_name)
- access_code = "attributes_cache[attr_name] ||= (#{access_code})"
- end
+ def external_attribute_access_code(attr_name, cast_code)
+ access_code = "v && #{cast_code}"
- access_code
+ if cache_attribute?(attr_name)
+ access_code = "attributes_cache[attr_name] ||= (#{access_code})"
end
- def attribute_cast_code(attr_name)
- columns_hash[attr_name].type_cast_code('v')
- end
+ access_code
+ end
+
+ def attribute_cast_code(attr_name)
+ columns_hash[attr_name].type_cast_code('v')
+ end
end
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
Please sign in to comment.
Something went wrong with that request. Please try again.