lib/delorean/base.rb in delorean_lang-0.3.2 vs lib/delorean/base.rb in delorean_lang-0.3.3
- old
+ new
@@ -5,66 +5,69 @@
# FIXME: the whitelist is quite hacky. It's currently difficult to
# override it. A user will likely want to directly modify this
# hash. The whole whitelist mechanism should be eventually
# rethought.
RUBY_WHITELIST = {
- compact: [Array],
- flatten: [Array, [Fixnum, nil]],
- length: [[Array, String]],
- max: [Array],
- member: "member?",
- member?: [Array, [Fixnum, String]],
- reverse: [Array],
- slice: [Array, Fixnum, Fixnum],
- sort: [Array],
- split: [String, String],
- uniq: [Array],
- sum: [Array],
- zip: [Array, [Array, Array, Array]],
- index: [Array, [Integer, Numeric, String, Array, Fixnum]],
- product: [Array, Array],
- first: [Enumerable, [nil, Fixnum]],
+ compact: [Array],
+ to_set: [Array],
+ flatten: [Array, [Fixnum, nil]],
+ length: [[Array, String]],
+ max: [Array],
+ member: "member?",
+ member?: [Array, [Fixnum, String]],
+ reverse: [Array],
+ slice: [Array, Fixnum, Fixnum],
+ sort: [Array],
+ split: [String, String],
+ uniq: [Array],
+ sum: [Array],
+ zip: [Array, [Array, Array, Array]],
+ index: [Array, [Integer, Numeric, String, Array, Fixnum]],
+ product: [Array, Array],
+ first: [Enumerable, [nil, Fixnum]],
+ intersection: [Set, Enumerable],
+ union: [Set, Enumerable],
- keys: [Hash],
- values: [Hash],
- upcase: [String],
- downcase: [String],
- match: [String, [String], [nil, Fixnum]],
+ keys: [Hash],
+ values: [Hash],
+ upcase: [String],
+ downcase: [String],
+ match: [String, [String], [nil, Fixnum]],
- hour: [[Date, Time, ActiveSupport::TimeWithZone]],
- min: [[Date, Time, ActiveSupport::TimeWithZone, Array]],
- sec: [[Date, Time, ActiveSupport::TimeWithZone]],
- to_date: [[Date, Time, ActiveSupport::TimeWithZone]],
+ hour: [[Date, Time, ActiveSupport::TimeWithZone]],
+ min: [[Date, Time, ActiveSupport::TimeWithZone, Array]],
+ sec: [[Date, Time, ActiveSupport::TimeWithZone]],
+ to_date: [[Date, Time, ActiveSupport::TimeWithZone]],
- month: [[Date, Time, ActiveSupport::TimeWithZone]],
- day: [[Date, Time, ActiveSupport::TimeWithZone]],
- year: [[Date, Time, ActiveSupport::TimeWithZone]],
+ month: [[Date, Time, ActiveSupport::TimeWithZone]],
+ day: [[Date, Time, ActiveSupport::TimeWithZone]],
+ year: [[Date, Time, ActiveSupport::TimeWithZone]],
- next_month: [[Date, Time, ActiveSupport::TimeWithZone],
- [nil, Fixnum],
- ],
- prev_month: [[Date, Time, ActiveSupport::TimeWithZone],
- [nil, Fixnum],
- ],
+ next_month: [[Date, Time, ActiveSupport::TimeWithZone],
+ [nil, Fixnum],
+ ],
+ prev_month: [[Date, Time, ActiveSupport::TimeWithZone],
+ [nil, Fixnum],
+ ],
beginning_of_month: [[Date, Time, ActiveSupport::TimeWithZone]],
end_of_month: [[Date, Time, ActiveSupport::TimeWithZone]],
- next_day: [[Date, Time, ActiveSupport::TimeWithZone],
- [nil, Fixnum],
- ],
- prev_day: [[Date, Time, ActiveSupport::TimeWithZone],
- [nil, Fixnum],
- ],
+ next_day: [[Date, Time, ActiveSupport::TimeWithZone],
+ [nil, Fixnum],
+ ],
+ prev_day: [[Date, Time, ActiveSupport::TimeWithZone],
+ [nil, Fixnum],
+ ],
- to_i: [[Numeric, String]],
- to_f: [[Numeric, String]],
- to_d: [[Numeric, String]],
- to_s: [Object],
- abs: [Numeric],
- round: [Numeric, [nil, Integer]],
+ to_i: [[Numeric, String]],
+ to_f: [[Numeric, String]],
+ to_d: [[Numeric, String]],
+ to_s: [Object],
+ abs: [Numeric],
+ round: [Numeric, [nil, Integer]],
}
module BaseModule
class NodeCall < Struct.new(:_e, :engine, :node, :params)
def evaluate(attr)
@@ -108,28 +111,25 @@
return obj.read_attribute(attr) if
klass.attribute_names.member? attr
return obj.send(attr.to_sym) if
klass.reflect_on_all_associations.map(&:name).member? attr.to_sym
-
- # FIXME: should call _instance_call for other types as well.
- # Too lazy to implement this now.
- begin
- return _instance_call(obj, attr, [])
- rescue
- raise InvalidGetAttribute, "ActiveRecord lookup '#{attr}' on #{obj}"
- end
elsif obj.instance_of?(NodeCall)
return obj.evaluate(attr)
elsif obj.instance_of?(Hash)
return obj[attr] if obj.member?(attr)
return attr.is_a?(String) ? obj[attr.to_sym] : nil
elsif obj.instance_of?(Class) && (obj < BaseClass)
return obj.send((attr + POST).to_sym, _e)
end
- raise InvalidGetAttribute,
- "bad attribute lookup '#{attr}' on <#{obj.class}> #{obj}"
+
+ begin
+ return _instance_call(obj, attr, [], _e)
+ rescue
+ raise InvalidGetAttribute,
+ "bad attribute lookup '#{attr}' on <#{obj.class}> #{obj}"
+ end
end
######################################################################
def self._index(obj, args, _e)
@@ -154,11 +154,11 @@
######################################################################
def self._sanitize_hash(_e)
_e.each_with_object({}) do
|(k,v), h|
- h[k] = v if k =~ /\A[a-z][A-Za-z0-9_]*\z/
+ h[k] = v if k.is_a?(Integer) || k =~ /\A[a-z][A-Za-z0-9_]*\z/
end
end
######################################################################
@@ -180,22 +180,29 @@
NodeCall.new(_e, engine, node || self, params)
end
######################################################################
- def self._instance_call(obj, method, args)
+ def self._instance_call(obj, method, args, _e)
begin
msg = method.to_sym
rescue NoMethodError
raise "bad method #{method}"
end
+ # FIXME: this is pretty hacky -- should probably merge
+ # RUBY_WHITELIST and SIG mechanisms.
+ if obj.is_a?(Class)
+ _e[:_engine].parse_check_call_fn(method, args.count, obj)
+ return obj.send(msg, *args)
+ end
+
sig = RUBY_WHITELIST[msg]
raise "no such method #{method}" unless sig
# if sig is a string, then method mapped to another name
- return _instance_call(obj, sig, args) if sig.is_a? String
+ return _instance_call(obj, sig, args, _e) if sig.is_a? String
raise "too many args to #{method}" if args.length>(sig.length-1)
arglist = [obj] + args