Class: IRuby::Kernel

Inherits:
Object
  • Object
show all
Defined in:
lib/iruby/kernel.rb

Constant Summary collapse

RED =
"\e[31m"
WHITE =
"\e[37m"
RESET =
"\e[0m"

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_file) ⇒ Kernel

Returns a new instance of Kernel


13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/iruby/kernel.rb', line 13

def initialize(config_file)
  @config = MultiJson.load(File.read(config_file))
  IRuby.logger.debug("IRuby kernel start with config #{@config}")
  Kernel.instance = self

  @session = Session.new(@config)
  $stdout = OStream.new(@session, :stdout)
  $stderr = OStream.new(@session, :stderr)

  @execution_count = 0
  @backend = create_backend
  @running = true
end

Class Attribute Details

.instanceObject

Returns the value of attribute instance


8
9
10
# File 'lib/iruby/kernel.rb', line 8

def instance
  @instance
end

Instance Attribute Details

#sessionObject (readonly)

Returns the value of attribute session


11
12
13
# File 'lib/iruby/kernel.rb', line 11

def session
  @session
end

Instance Method Details

#comm_close(msg) ⇒ Object


159
160
161
162
163
# File 'lib/iruby/kernel.rb', line 159

def comm_close(msg)
  comm_id = msg[:content]['comm_id']
  Comm.comm[comm_id].handle_close(msg[:content]['data'])
  Comm.comm.delete(comm_id)
end

#comm_msg(msg) ⇒ Object


155
156
157
# File 'lib/iruby/kernel.rb', line 155

def comm_msg(msg)
  Comm.comm[msg[:content]['comm_id']].handle_msg(msg[:content]['data'])
end

#comm_open(msg) ⇒ Object


149
150
151
152
153
# File 'lib/iruby/kernel.rb', line 149

def comm_open(msg)
  comm_id = msg[:content]['comm_id']
  target_name = msg[:content]['target_name']
  Comm.comm[comm_id] = Comm.target[target_name].new(target_name, comm_id)
end

#complete_request(msg) ⇒ Object


109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/iruby/kernel.rb', line 109

def complete_request(msg)
  # HACK for #26, only complete last line
  code = msg[:content]['code']
  if start = code.rindex("\n")
    code = code[start+1..-1]
    start += 1
  end
  @session.send(:reply, :complete_reply,
                matches: @backend.complete(code),
                status: :ok,
                cursor_start: start.to_i,
                cursor_end: msg[:content]['cursor_pos'])
end

#connect_request(msg) ⇒ Object


123
124
125
# File 'lib/iruby/kernel.rb', line 123

def connect_request(msg)
  @session.send(:reply, :connect_reply, Hash[%w(shell_port iopub_port stdin_port hb_port).map {|k| [k, @config[k]] }])
end

#create_backendObject


27
28
29
30
31
32
# File 'lib/iruby/kernel.rb', line 27

def create_backend
  PryBackend.new
rescue Exception => e
  IRuby.logger.warn "Could not load PryBackend: #{e.message}\n#{e.backtrace.join("\n")}" unless LoadError === e
  PlainBackend.new
end

#dispatchObject


41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/iruby/kernel.rb', line 41

def dispatch
  msg = @session.recv(:reply)
  type = msg[:header]['msg_type']
  raise "Unknown message type: #{msg.inspect}" unless type =~ /comm_|_request\Z/ && respond_to?(type)
  begin
    send_status :busy
    send(type, msg)
  ensure
    send_status :idle
  end
rescue Exception => e
  IRuby.logger.debug "Kernel error: #{e.message}\n#{e.backtrace.join("\n")}"
  @session.send(:publish, :error, error_message(e))
end

#error_message(e) ⇒ Object


101
102
103
104
105
106
107
# File 'lib/iruby/kernel.rb', line 101

def error_message(e)
  { status: :error,
    ename: e.class.to_s,
    evalue: e.message,
    traceback: ["#{RED}#{e.class}#{RESET}: #{e.message}", *e.backtrace.map { |l| "#{WHITE}#{l}#{RESET}" }],
    execution_count: @execution_count }
end

#execute_request(msg) ⇒ Object


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/iruby/kernel.rb', line 74

def execute_request(msg)
  code = msg[:content]['code']
  @execution_count += 1 if msg[:content]['store_history']
  @session.send(:publish, :execute_input, code: code, execution_count: @execution_count)

  content = {
    status: :ok,
    payload: [],
    user_expressions: {},
    execution_count: @execution_count
  }
  result = nil
  begin
    result = @backend.eval(code, msg[:content]['store_history'])
  rescue SystemExit
    content[:payload] << { source: :ask_exit }
  rescue Exception => e
    content = error_message(e)
    @session.send(:publish, :error, content)
  end
  @session.send(:reply, :execute_reply, content)
  @session.send(:publish, :execute_result,
                data: Display.display(result),
                metadata: {},
                execution_count: @execution_count) unless result.nil? || msg[:content]['silent']
end

#history_request(msg) ⇒ Object


132
133
134
135
136
# File 'lib/iruby/kernel.rb', line 132

def history_request(msg)
  # we will just send back empty history for now, pending clarification
  # as requested in ipython/ipython#3806
  @session.send(:reply, :history_reply, history: [])
end

#inspect_request(msg) ⇒ Object


138
139
140
141
142
143
144
145
146
147
# File 'lib/iruby/kernel.rb', line 138

def inspect_request(msg)
  result = @backend.eval(msg[:content]['code'])
  @session.send(:reply, :inspect_reply,
                status: :ok,
                data: Display.display(result),
                metadata: {})
rescue Exception => e
  IRuby.logger.warn "Inspection error: #{e.message}\n#{e.backtrace.join("\n")}"
  @session.send(:reply, :inspect_reply, status: :error)
end

#kernel_info_request(msg) ⇒ Object


56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/iruby/kernel.rb', line 56

def kernel_info_request(msg)
  @session.send(:reply, :kernel_info_reply,
                protocol_version: '5.0',
                implementation: 'iruby',
                banner: "IRuby #{IRuby::VERSION}",
                implementation_version: IRuby::VERSION,
                language_info: {
                  name: 'ruby',
                  version: RUBY_VERSION,
                  mimetype: 'application/x-ruby',
                  file_extension: '.rb'
                })
end

#runObject


34
35
36
37
38
39
# File 'lib/iruby/kernel.rb', line 34

def run
  send_status :starting
  while @running
    dispatch
  end
end

#send_status(status) ⇒ Object


70
71
72
# File 'lib/iruby/kernel.rb', line 70

def send_status(status)
  @session.send(:publish, :status, execution_state: status)
end

#shutdown_request(msg) ⇒ Object


127
128
129
130
# File 'lib/iruby/kernel.rb', line 127

def shutdown_request(msg)
  @session.send(:reply, :shutdown_reply, msg[:content])
  @running = false
end