File: calls.rb

package info (click to toggle)
ruby-celluloid 0.18.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 848 kB
  • sloc: ruby: 7,579; makefile: 10
file content (62 lines) | stat: -rw-r--r-- 1,772 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
module Celluloid
  # Calls represent requests to an actor
  class Call
    attr_reader :method, :arguments, :block

    def initialize(method, arguments = [], block = nil)
      @retry = 0
      @method = method
      @arguments = arguments
      if block
        if Celluloid.exclusive?
          # FIXME: nicer exception
          raise "Cannot execute blocks on sender in exclusive mode"
        end
        @block = Proxy::Block.new(Celluloid.mailbox, self, block)
      else
        @block = nil
      end
    end

    def execute_block_on_receiver
      @block && @block.execution = :receiver
    end

    def dispatch(obj)
      check(obj)
      obj.public_send(@method, *@arguments, &(@block && @block.to_proc))
    end

    def check(obj)
      # NOTE: don't use respond_to? here
      begin
        meth = obj.method(@method)
      rescue NameError
        raise NoMethodError, "undefined method `#{@method}' for #<#{obj.class}:0x#{obj.object_id.to_s(16)}>"
      end

      arity = meth.arity

      if arity >= 0
        if @arguments.size != arity
          e = ArgumentError.new("wrong number of arguments (#{@arguments.size} for #{arity})")
          e.set_backtrace(caller << "#{meth.source_location.join(':')}: in `#{meth.name}`")
          raise e
        end
      elsif arity < -1
        mandatory_args = -arity - 1
        if arguments.size < mandatory_args
          e = ArgumentError.new("wrong number of arguments (#{@arguments.size} for #{mandatory_args}+)")
          e.set_backtrace(caller << "#{meth.source_location.join(':')}: in `#{meth.name}`")
          raise e
        end
      end
    rescue => ex
      raise AbortError, ex
    end
  end
end

require "celluloid/call/sync"
require "celluloid/call/async"
require "celluloid/call/block"