Temporary tag for this failure. Updated CI spec coming.
[rbx.git] / kernel / core / proc.rb
blob7e56905fc428658bba91d84d0ed155c8d88b0c5d
1 # depends on: class.rb
3 class Proc
4   self.instance_fields = 3
5   ivar_as_index :__ivars__ => 0, :block => 1, :check_args => 2
7   def block; @block ; end
9   def block=(other)
10     @block = other
11   end
13   def check_args=(other)
14     @check_args = other
15   end
17   def binding
18     Binding.setup @block.home
19   end
21   #--
22   # An optimized version, used for the &block syntax
23   #++
25   def self.__from_block__(env)
26     if env.__kind_of__(BlockEnvironment)
27       obj = allocate()
28       obj.block = env
29       return obj
30     else
31       begin
32         env.to_proc
33       rescue Exception
34         raise ArgumentError, "Unable to convert #{env.inspect} to a Proc"
35       end
36     end
37   end
39   def self.from_environment(env, check_args=false)
40     if env.nil?
41       nil
42     elsif env.kind_of?(BlockEnvironment)
43       obj = allocate()
44       obj.block = env
45       obj.check_args = check_args
46       obj
47     elsif env.respond_to? :to_proc
48       env.to_proc
49     else
50       raise ArgumentError.new("Unable to turn a #{env.inspect} into a Proc")
51     end
52   end
54   def self.new(&block)
55     if block
56       return block
57     else
58       # This behavior is stupid.
59       be = MethodContext.current.sender.block
60       if be
61         return from_environment(be)
62       else
63         raise ArgumentError, "tried to create a Proc object without a block"
64       end
65     end
66   end
68   def inspect
69     "#<#{self.class}:0x#{self.object_id.to_s(16)} @ #{self.block.file}:#{self.block.line}>"
70   end
72   alias_method :to_s, :inspect
74   def ==(other)
75     return false unless other.kind_of? self.class
76     @block == other.block
77   end
79   def arity
80     @block.arity
81   end
83   def to_proc
84     self
85   end
87   def call(*args)
88     @block.call(*args)
89   end
91   alias_method :[], :call
93   class Function < Proc
94     ivar_as_index :block => 1
96     def call(*args)
97       a = arity()
98       unless a < 0 or a == 1 or args.size == a
99         raise ArgumentError, "wrong number of arguments (#{args.size} for #{arity})"
100       end
102       begin
103         @block.call(*args)
104       rescue IllegalLongReturn, LongReturnException => e
105         return e.value
106       end
107     end
108     
109     alias_method :[], :call
110   end