lib/delorean/base.rb in delorean_lang-0.6.3 vs lib/delorean/base.rb in delorean_lang-1.0.0

- old
+ new

@@ -64,19 +64,12 @@ # case statement below. However, Gemini appears to create Hash # objects when running Delorean modules in delayed jobs that # return true when we called obj.instance_of?(Hash) and do not # work with the "case/when" matcher!!! For now, this is a # hacky workaround. This is likely some sort of Ruby bug. - if obj.instance_of?(Hash) - # FIXME: this implementation doesn't handle something like - # {}.length. i.e. length is a whitelisted function, but not - # an attr. This implementation returns nil instead of 0. - return obj[attr] if obj.member?(attr) + return _get_hash_attr(obj, attr, _e) if obj.instance_of?(Hash) - return attr.is_a?(String) ? obj[attr.to_sym] : nil - end - # NOTE: should keep this function consistent with _index case obj when nil # FIXME: even Javascript which is superpermissive raises an # exception on null getattr. @@ -97,19 +90,46 @@ "attr lookup failed: '#{attr}' on <#{obj.class}> #{obj} - #{exc}" ) end end + def self._get_hash_attr(obj, attr, _e, index_call = false) + return obj[attr] if obj.key?(attr) + + return obj[attr.to_sym] if attr.is_a?(String) && obj.key?(attr.to_sym) + + # Shouldn't try to call the method if hash['length'] was called. + return nil if index_call + + # Return nil when it's obviously not a method + return nil unless attr.is_a?(String) || attr.is_a?(Symbol) + + # hash.length might be either hash['length'] or hash.length call. + # If key is not found, check if object responds to method and call it. + # If not succeeded, return nil, assuming that it was an attribute call. + return nil unless obj.respond_to?(attr) + + begin + return _instance_call(obj, attr, [], _e) + rescue StandardError + return nil + end + end + ###################################################################### def self._index(obj, args, _e) # NOTE: should keep this function consistent with _get_attr case obj when nil # FIXME: even Javascript which is superpermissive raises an # exception on null getattr. nil - when Hash, NodeCall, Class, OpenStruct + when Hash + raise InvalidIndex unless args.length == 1 + + _get_hash_attr(obj, args[0], _e, true) + when NodeCall, Class, OpenStruct raise InvalidIndex unless args.length == 1 _get_attr(obj, args[0], _e) when Array, String, MatchData raise InvalidIndex unless args.length <= 2 &&