iruby 0.1.13 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/iruby.gemspec CHANGED
@@ -6,14 +6,14 @@ Gem::Specification.new do |s|
6
6
  s.name = 'iruby'
7
7
  s.date = Date.today.to_s
8
8
  s.version = IRuby::VERSION
9
- s.authors = ['Damián Silvani', 'Min RK', 'Martin Sarsale', 'Josh Adams', 'Daniel Mendler']
10
- s.email = ['benjaminrk@gmail.com']
9
+ s.authors = ['Daniel Mendler', 'The SciRuby developers']
10
+ s.email = ['mail@daniel-mendler.de']
11
11
  s.description = 'Ruby Kernel for IPython'
12
12
  s.summary = 'A Ruby kernel for IPython frontends (notebook console, etc.)'
13
- s.homepage = 'https://github.com/minad/iruby'
13
+ s.homepage = 'https://github.com/SciRuby/iruby'
14
14
  s.license = 'MIT'
15
15
 
16
- s.files = `git ls-files`.split($/)
16
+ s.files = `git ls-files`.split($/).reject {|f| f =~ /\Aattic/ }
17
17
  s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  s.test_files = s.files.grep(%r{^test/})
19
19
  s.require_paths = %w(lib)
@@ -22,10 +22,13 @@ Gem::Specification.new do |s|
22
22
  File.read('Gemfile').scan(/gem\s+'(.*?)'/) { m << " * #{$1}\n" }
23
23
  s.post_install_message = m << "\n"
24
24
 
25
- s.add_development_dependency 'rake'
25
+ s.required_ruby_version = '>= 2.0.0'
26
26
 
27
- s.add_runtime_dependency 'bond', '~> 0.5.0'
28
- s.add_runtime_dependency 'ffi-rzmq', '~> 2.0'
29
- s.add_runtime_dependency 'multi_json', '~> 1.10.0'
30
- s.add_runtime_dependency 'mimemagic', '~> 0.2.0'
27
+ s.add_development_dependency 'rake', '~> 10.4'
28
+ s.add_development_dependency 'minitest', '~> 5.6'
29
+
30
+ s.add_runtime_dependency 'bond', '~> 0.5'
31
+ s.add_runtime_dependency 'rbczmq', '~> 1.7'
32
+ s.add_runtime_dependency 'multi_json', '~> 1.11'
33
+ s.add_runtime_dependency 'mimemagic', '~> 0.3'
31
34
  end
data/lib/iruby.rb CHANGED
@@ -1,4 +1,4 @@
1
- require 'ffi-rzmq'
1
+ require 'rbczmq'
2
2
  require 'mimemagic'
3
3
  require 'multi_json'
4
4
  require 'bond'
@@ -14,3 +14,4 @@ require 'iruby/ostream'
14
14
  require 'iruby/formatter'
15
15
  require 'iruby/utils'
16
16
  require 'iruby/display'
17
+ require 'iruby/comm'
data/lib/iruby/backend.rb CHANGED
@@ -8,8 +8,8 @@ module IRuby
8
8
  TOPLEVEL_BINDING.eval(code)
9
9
  end
10
10
 
11
- def complete(line, text)
12
- Bond.agent.call(line, line)
11
+ def complete(code)
12
+ Bond.agent.call(code, code)
13
13
  end
14
14
  end
15
15
 
@@ -25,14 +25,14 @@ module IRuby
25
25
 
26
26
  def eval(code)
27
27
  @pry.last_result = nil
28
- @pry.eval(code)
28
+ raise SystemExit unless @pry.eval(code)
29
29
  raise @pry.last_exception if @pry.last_result_is_exception?
30
30
  @pry.push_initial_binding unless @pry.current_binding
31
31
  @pry.last_result
32
32
  end
33
33
 
34
- def complete(line, text)
35
- @pry.complete(line)
34
+ def complete(code)
35
+ @pry.complete(code)
36
36
  end
37
37
  end
38
38
  end
data/lib/iruby/comm.rb ADDED
@@ -0,0 +1,60 @@
1
+ module IRuby
2
+ # Comm is a new messaging system for bidirectional communication.
3
+ # Both kernel and front-end listens for messages.
4
+ class Comm
5
+ attr_writer :on_msg, :on_close
6
+
7
+ class << self
8
+ def targets
9
+ @targets ||= {}
10
+ end
11
+ end
12
+
13
+ def initialize(target_name, comm_id = SecureRandom.uuid)
14
+ @target_name, @comm_id = target_name, comm_id
15
+ end
16
+
17
+ def open(**data)
18
+ content = {
19
+ comm_id: @comm_id,
20
+ data: data,
21
+ target_name: @target_name
22
+ }
23
+ Kernel.instance.session.send(:publish, 'comm_open', content)
24
+ Kernel.instance.comms[@comm_id] = self
25
+ end
26
+
27
+ def send(**data)
28
+ content = {
29
+ comm_id: @comm_id,
30
+ data: data
31
+ }
32
+ Kernel.instance.session.send(:publish, 'comm_msg', content)
33
+ end
34
+
35
+ def close(**data)
36
+ content = {
37
+ comm_id: @comm_id,
38
+ data: data
39
+ }
40
+ Kernel.instance.session.send(:publish, 'comm_close', content)
41
+ Kernel.instance.comms.delete(@comm_id)
42
+ end
43
+
44
+ def on_msg(&b)
45
+ @on_msg = b
46
+ end
47
+
48
+ def on_close(&b)
49
+ @on_close = b
50
+ end
51
+
52
+ def comm_msg(msg)
53
+ @on_msg.call(msg) if @on_msg
54
+ end
55
+
56
+ def comm_close
57
+ @on_close.call if @on_close
58
+ end
59
+ end
60
+ end
data/lib/iruby/command.rb CHANGED
@@ -1,18 +1,32 @@
1
- require 'shellwords'
2
- require 'fileutils'
3
-
4
1
  module IRuby
5
2
  class Command
6
- IRUBYDIR = '~/.config/iruby'
7
-
8
3
  def initialize(args)
9
4
  @args = args
5
+
6
+ ipython_dir = ENV['IPYTHONDIR'] || '~/.ipython'
7
+ @args.each do |arg|
8
+ ipython_dir = $1 if arg =~ /\A--ipython-dir=(.*)\Z/
9
+ end
10
+ ipython_dir = File.expand_path(ipython_dir)
11
+ @kernel_file = File.join(ipython_dir, 'kernels', 'ruby', 'kernel.json')
10
12
  end
11
13
 
12
14
  def run
13
- raise 'Use --iruby-dir instead of --ipython-dir!' unless @args.grep(/\A--ipython-dir=.*\Z/).empty?
14
-
15
- if @args.first == 'kernel'
15
+ case @args.first
16
+ when 'version', '-v', '--version'
17
+ require 'iruby/version'
18
+ puts IRuby::VERSION
19
+ when 'help', '-h', '--help'
20
+ print_help
21
+ when 'register'
22
+ if File.exist?(@kernel_file) && !@args.include?('--force')
23
+ STDERR.puts "#{@kernel_file} already exists!\nUse --force to force a register."
24
+ exit 1
25
+ end
26
+ register_kernel
27
+ when 'unregister'
28
+ unregister_kernel
29
+ when 'kernel'
16
30
  run_kernel
17
31
  else
18
32
  run_ipython
@@ -21,20 +35,49 @@ module IRuby
21
35
 
22
36
  private
23
37
 
38
+ def print_help
39
+ puts %{
40
+ Usage:
41
+ iruby register Register IRuby kernel into #{@kernel_file}.
42
+ iruby unregister Remove #{@kernel_file}.
43
+ iruby console Launch the IRuby terminal-based console.
44
+ iruby notebook Launch the IRuby HTML notebook server.
45
+ ... Same as IPython.
46
+
47
+ Please note that IRuby accepts the same parameters as IPython.
48
+ Try `ipython help` for more information.
49
+ }
50
+ end
51
+
24
52
  def run_kernel
53
+ require 'iruby/logger'
54
+ loggers = [Logger.new(STDOUT)]
55
+ @args.each do |arg|
56
+ loggers << Logger.new($1) if arg =~ /\A--log=(.*)\Z/
57
+ end
58
+ IRuby.logger = MultiLogger.new(*loggers)
59
+ IRuby.logger.level = @args.include?('--debug') ? Logger::DEBUG : Logger::INFO
60
+
25
61
  raise(ArgumentError, 'Not enough arguments to the kernel') if @args.size < 2 || @args.size > 4
26
62
  config_file, boot_file, working_dir = @args[1..-1]
27
63
  Dir.chdir(working_dir) if working_dir
64
+
28
65
  require boot_file if boot_file
66
+
67
+ begin
68
+ require 'bundler/setup'
69
+ rescue Exception
70
+ end
71
+
29
72
  require 'iruby'
30
73
  Kernel.new(config_file).run
31
74
  rescue Exception => ex
32
- STDERR.puts "Kernel died: #{ex.message}\n#{ex.backtrace.join("\n")}"
75
+ IRuby.logger.fatal "Kernel died: #{ex.message}\n#{ex.backtrace.join("\n")}"
33
76
  raise
34
77
  end
35
78
 
36
79
  def check_version
37
- required = '1.2.0'
80
+ required = '3.0.0'
38
81
  version = `ipython --version`.chomp
39
82
  if version < required
40
83
  STDERR.puts "Your IPython version #{version} is too old, at least #{required} is required"
@@ -45,55 +88,27 @@ module IRuby
45
88
  def run_ipython
46
89
  check_version
47
90
 
48
- dir = @args.grep(/\A--iruby-dir=.*\Z/)
49
- @args -= dir
50
- dir = dir.last.to_s.sub(/\A--profile=/, '')
51
- dir = ENV['IRUBYDIR'] || IRUBYDIR if dir.empty?
52
- dir = File.expand_path(dir)
53
- ENV['IPYTHONDIR'] = dir
54
-
55
- if @args.size == 3 && @args[0] == 'profile' && @args[1] == 'create'
56
- profile = @args[2]
57
- else
58
- profile = @args.grep(/\A--profile=.*\Z/).last.to_s.sub(/\A--profile=/, '')
59
- profile = 'default' if profile.empty?
60
- end
61
-
62
- create_profile(dir, profile)
63
-
64
91
  # We must use the console to launch the whole 0MQ-client-server stack
65
- @args = %w(console --no-banner) + @args if @args.first.to_s !~ /\A\w+\Z/
92
+ @args = %w(console) + @args if @args.first.to_s !~ /\A\w/
93
+ register_kernel if %w(console qtconsole notebook).include?(@args.first) && !File.exist?(@kernel_file)
94
+ @args += %w(--kernel ruby) if %w(console qtconsole).include? @args.first
66
95
 
67
96
  Kernel.exec('ipython', *@args)
68
97
  end
69
98
 
70
- def create_profile(dir, profile)
71
- profile_dir = File.join(dir, "profile_#{profile}")
72
- unless File.directory?(profile_dir)
73
- puts "Creating profile directory #{profile_dir}"
74
- `ipython profile create #{Shellwords.escape profile}`
75
- end
76
-
77
- kernel_cmd = []
78
- kernel_cmd << ENV['BUNDLE_BIN_PATH'] << 'exec' if ENV['BUNDLE_BIN_PATH']
79
- kernel_cmd += [File.expand_path($0), 'kernel', '{connection_file}']
80
- kernel_cmd = "c.KernelManager.kernel_cmd = #{kernel_cmd.inspect}"
81
- Dir[File.join(profile_dir, '*_config.py')].each do |path|
82
- content = File.read(path)
83
- content << kernel_cmd unless content.gsub!(/^c\.KernelManager\.kernel_cmd.*$/, kernel_cmd)
84
- File.open(path, 'w') {|f| f.write(content) }
85
- end
99
+ def register_kernel
100
+ require 'fileutils'
101
+ FileUtils.mkpath(File.dirname(@kernel_file))
102
+ File.write(@kernel_file, %{{
103
+ "argv": [ "#{File.expand_path $0}", "kernel", "{connection_file}" ],
104
+ "display_name": "Ruby",
105
+ "language": "ruby"
106
+ }
107
+ })
108
+ end
86
109
 
87
- static_dir = File.join(profile_dir, 'static')
88
- target_dir = File.join(File.dirname(__FILE__), 'static')
89
- unless (File.readlink(static_dir) rescue nil) == target_dir
90
- FileUtils.rm_rf(static_dir) rescue nil
91
- begin
92
- FileUtils.ln_sf(target_dir, static_dir)
93
- rescue => ex
94
- STDERR.puts "Could not create directory #{static_dir}: #{ex.message}"
95
- end
96
- end
110
+ def unregister_kernel
111
+ File.unlink(@kernel_file)
97
112
  end
98
113
  end
99
114
  end
data/lib/iruby/display.rb CHANGED
@@ -30,12 +30,6 @@ module IRuby
30
30
  # as the given mime type.
31
31
  data[exact_mime] = protect(exact_mime, obj) if exact_mime && !data.any? {|m,_| exact_mime == m }
32
32
 
33
- # HACK for IPython #6259
34
- # https://github.com/ipython/ipython/issues/6259
35
- if js = data.delete('application/javascript')
36
- data['text/html'] = "<script type='text/javascript'>#{js}</script>"
37
- end
38
-
39
33
  data
40
34
  end
41
35
 
@@ -173,7 +167,7 @@ module IRuby
173
167
  type { NArray }
174
168
  format 'text/latex' do |obj|
175
169
  obj.dim == 2 ?
176
- LaTeX.matrix(obj.transpose, obj.shape[1], obj.shape[0]) :
170
+ LaTeX.matrix(obj.transpose(1, 0), obj.shape[1], obj.shape[0]) :
177
171
  LaTeX.vector(obj.to_a)
178
172
  end
179
173
  format 'text/html' do |obj|
@@ -182,7 +176,7 @@ module IRuby
182
176
 
183
177
  type { Matrix }
184
178
  format 'text/latex' do |obj|
185
- LaTeX.matrix(obj, obj.row_count, obj.column_count)
179
+ LaTeX.matrix(obj, obj.row_size, obj.column_size)
186
180
  end
187
181
  format 'text/html' do |obj|
188
182
  HTML.table(obj.to_a)
@@ -228,8 +222,8 @@ module IRuby
228
222
  end
229
223
 
230
224
  match do |obj|
231
- defined?(Magic::Image) && Magic::Image === obj ||
232
- defined?(MiniMagic::Image) && MiniMagic::Image === obj
225
+ defined?(Magick::Image) && Magick::Image === obj ||
226
+ defined?(MiniMagick::Image) && MiniMagick::Image === obj
233
227
  end
234
228
  format 'image' do |obj|
235
229
  format = obj.format || 'PNG'
@@ -24,11 +24,9 @@ module IRuby
24
24
  module HTML
25
25
  extend self
26
26
 
27
- def table(obj, options = {})
28
- options[:maxrows] = 15 unless options.include?(:maxrows)
29
- options[:maxcols] = 15 unless options.include?(:maxcols)
30
- raise ArgumentError, 'Invalid :maxrows' if options[:maxrows] && options[:maxrows] < 3
31
- raise ArgumentError, 'Invalid :maxcols' if options[:maxcols] && options[:maxcols] < 3
27
+ def table(obj, maxrows: 15, maxcols: 15, **options)
28
+ raise ArgumentError, 'Invalid :maxrows' if maxrows && maxrows < 3
29
+ raise ArgumentError, 'Invalid :maxcols' if maxcols && maxcols < 3
32
30
 
33
31
  return obj unless obj.respond_to?(:each)
34
32
 
@@ -77,18 +75,18 @@ module IRuby
77
75
  keys1, keys2 = keys, nil
78
76
  header1, header2 = header, nil
79
77
 
80
- if options[:maxcols] && keys.size > options[:maxcols]
81
- keys1 = keys[0...options[:maxcols] / 2]
82
- keys2 = keys[-options[:maxcols] / 2...-1]
78
+ if maxcols && keys.size > maxcols
79
+ keys1 = keys[0...maxcols / 2]
80
+ keys2 = keys[-maxcols / 2...-1]
83
81
  if header
84
- header1 = header[0...options[:maxcols] / 2]
85
- header2 = header[-options[:maxcols] / 2...-1]
82
+ header1 = header[0...maxcols / 2]
83
+ header2 = header[-maxcols / 2...-1]
86
84
  end
87
85
  end
88
86
 
89
- if options[:maxrows] && rows.size > options[:maxrows]
90
- rows1 = rows[0...options[:maxrows] / 2]
91
- rows2 = rows[-options[:maxrows] / 2...-1]
87
+ if maxrows && rows.size > maxrows
88
+ rows1 = rows[0...maxrows / 2]
89
+ rows2 = rows[-maxrows / 2...-1]
92
90
  end
93
91
 
94
92
  table = '<table>'
data/lib/iruby/kernel.rb CHANGED
@@ -8,102 +8,96 @@ module IRuby
8
8
  attr_accessor :instance
9
9
  end
10
10
 
11
+ attr_reader :session, :comms
12
+
11
13
  def initialize(config_file)
12
14
  @config = MultiJson.load(File.read(config_file))
13
15
 
14
- #puts 'Starting the kernel'
15
- #puts config
16
- #puts 'Use Ctrl-\\ (NOT Ctrl-C!) to terminate.'
16
+ IRuby.logger.debug("IRuby kernel start with config #{@config}")
17
17
 
18
18
  Kernel.instance = self
19
19
 
20
20
  c = ZMQ::Context.new
21
21
 
22
22
  connection = "#{@config['transport']}://#{@config['ip']}:%d"
23
- @reply_socket = c.socket(ZMQ::XREP)
24
- @reply_socket.bind(connection % @config['shell_port'])
23
+ reply_socket = c.socket(:ROUTER)
24
+ reply_socket.bind(connection % @config['shell_port'])
25
25
 
26
- @pub_socket = c.socket(ZMQ::PUB)
27
- @pub_socket.bind(connection % @config['iopub_port'])
26
+ pub_socket = c.socket(:PUB)
27
+ pub_socket.bind(connection % @config['iopub_port'])
28
28
 
29
29
  Thread.new do
30
30
  begin
31
- hb_socket = c.socket(ZMQ::REP)
31
+ hb_socket = c.socket(:REP)
32
32
  hb_socket.bind(connection % @config['hb_port'])
33
- ZMQ::Device.new(hb_socket, hb_socket)
33
+ ZMQ.proxy(hb_socket, hb_socket)
34
34
  rescue Exception => ex
35
- STDERR.puts "Kernel heartbeat died: #{ex.message}\n"#{ex.backtrace.join("\n")}"
35
+ IRuby.logger.fatal "Kernel heartbeat died: #{ex.message}\n"#{ex.backtrace.join("\n")}"
36
36
  end
37
37
  end
38
38
 
39
- @session = Session.new('kernel', @config)
39
+ @session = Session.new('kernel', @config, publish: pub_socket, reply: reply_socket)
40
40
 
41
- $stdout = OStream.new(@session, @pub_socket, 'stdout')
42
- $stderr = OStream.new(@session, @pub_socket, 'stderr')
41
+ $stdout = OStream.new(@session, 'stdout')
42
+ $stderr = OStream.new(@session, 'stderr')
43
43
 
44
44
  @execution_count = 0
45
45
  @backend = create_backend
46
46
  @running = true
47
+ @comms = {}
47
48
  end
48
49
 
49
50
  def create_backend
50
51
  PryBackend.new
51
52
  rescue Exception => ex
52
- STDERR.puts ex.message unless LoadError === ex
53
+ IRuby.logger.warn ex.message unless LoadError === ex
53
54
  PlainBackend.new
54
55
  end
55
56
 
56
57
  def run
57
58
  send_status('starting')
58
59
  while @running
59
- ident, msg = @session.recv(@reply_socket, 0)
60
+ ident, msg = @session.recv(:reply)
60
61
  type = msg[:header]['msg_type']
61
- if type =~ /_request\Z/ && respond_to?(type)
62
+ if type =~ /comm_|_request\Z/ && respond_to?(type)
63
+ send_status('busy')
62
64
  send(type, ident, msg)
65
+ send_status('idle')
63
66
  else
64
- STDERR.puts "Unknown message type: #{msg[:header]['msg_type']} #{msg.inspect}"
67
+ IRuby.logger.error "Unknown message type: #{msg[:header]['msg_type']} #{msg.inspect}"
65
68
  end
66
69
  end
67
70
  end
68
71
 
69
- def display(obj, options={})
70
- unless obj.nil?
71
- content = { data: Display.display(obj, options), metadata: {}, execution_count: @execution_count }
72
- @session.send(@pub_socket, 'pyout', content)
73
- end
74
- nil
75
- end
76
-
77
72
  def kernel_info_request(ident, msg)
78
73
  content = {
79
- protocol_version: [4, 0],
80
-
81
- # Language version number (mandatory).
82
- # It is Python version number (e.g., [2, 7, 3]) for the kernel
83
- # included in IPython.
84
- language_version: RUBY_VERSION.split('.').map(&:to_i),
85
-
86
- # Programming language in which kernel is implemented (mandatory).
87
- # Kernel included in IPython returns 'python'.
88
- language: 'ruby'
74
+ protocol_version: '5.0',
75
+ implementation: 'iruby',
76
+ implementation_version: IRuby::VERSION,
77
+ language_info: {
78
+ name: 'ruby',
79
+ version: RUBY_VERSION,
80
+ mimetype: 'text/ruby',
81
+ file_extension: 'rb',
82
+ },
83
+ banner: "IRuby #{IRuby::VERSION}"
89
84
  }
90
- @session.send(@reply_socket, 'kernel_info_reply', content, ident)
85
+ @session.send(:reply, 'kernel_info_reply', content, ident)
91
86
  end
92
87
 
93
88
  def send_status(status)
94
- @session.send(@pub_socket, 'status', execution_state: status)
89
+ @session.send(:publish, 'status', {execution_state: status})
95
90
  end
96
91
 
97
92
  def execute_request(ident, msg)
98
93
  begin
99
94
  code = msg[:content]['code']
100
95
  rescue
101
- STDERR.puts "Got bad message: #{msg.inspect}"
96
+ IRuby.logger.fatal "Got bad message: #{msg.inspect}"
102
97
  return
103
98
  end
104
99
  @execution_count += 1 unless msg[:content].fetch('silent', false)
105
- send_status('busy')
106
- @session.send(@pub_socket, 'pyin', code: code)
100
+ @session.send(:publish, 'execute_input', {code: code, execution_count: @execution_count}, ident)
107
101
 
108
102
  result = nil
109
103
  begin
@@ -111,33 +105,35 @@ module IRuby
111
105
  content = {
112
106
  status: 'ok',
113
107
  payload: [],
114
- user_variables: {},
115
108
  user_expressions: {},
116
109
  execution_count: @execution_count
117
110
  }
111
+ rescue SystemExit
112
+ raise
118
113
  rescue Exception => e
119
114
  content = {
115
+ status: 'error',
120
116
  ename: e.class.to_s,
121
117
  evalue: e.message,
122
- etype: e.class.to_s,
123
- status: 'error',
124
118
  traceback: ["#{RED}#{e.class}#{RESET}: #{e.message}", *e.backtrace.map { |l| "#{WHITE}#{l}#{RESET}" }],
125
119
  execution_count: @execution_count
126
120
  }
127
- @session.send(@pub_socket, 'pyerr', content)
121
+ @session.send(:publish, 'error', content, ident)
122
+ end
123
+ @session.send(:reply, 'execute_reply', content, ident)
124
+ unless result.nil? || msg[:content]['silent']
125
+ @session.send(:publish, 'execute_result', data: Display.display(result), metadata: {}, execution_count: @execution_count)
128
126
  end
129
- @session.send(@reply_socket, 'execute_reply', content, ident)
130
- display(result) unless msg[:content]['silent']
131
- send_status('idle')
132
127
  end
133
128
 
134
129
  def complete_request(ident, msg)
135
130
  content = {
136
- matches: @backend.complete(msg[:content]['line'], msg[:content]['text']),
131
+ matches: @backend.complete(msg[:content]['code']),
137
132
  status: 'ok',
138
- matched_text: msg[:content]['line'],
133
+ cursor_start: 0,
134
+ cursor_end: msg[:content]['cursor_pos']
139
135
  }
140
- @session.send(@reply_socket, 'complete_reply', content, ident)
136
+ @session.send(:reply, 'complete_reply', content, ident)
141
137
  end
142
138
 
143
139
  def connect_request(ident, msg)
@@ -147,11 +143,11 @@ module IRuby
147
143
  stdin_port: config['stdin_port'],
148
144
  hb_port: config['hb_port']
149
145
  }
150
- @session.send(@reply_socket, 'connect_reply', content, ident)
146
+ @session.send(:reply, 'connect_reply', content, ident)
151
147
  end
152
148
 
153
149
  def shutdown_request(ident, msg)
154
- @session.send(@reply_socket, 'shutdown_reply', msg[:content], ident)
150
+ @session.send(:reply, 'shutdown_reply', msg[:content], ident)
155
151
  @running = false
156
152
  end
157
153
 
@@ -161,10 +157,10 @@ module IRuby
161
157
  content = {
162
158
  history: []
163
159
  }
164
- @session.send(@reply_socket, 'history_reply', content, ident)
160
+ @session.send(:reply, 'history_reply', content, ident)
165
161
  end
166
162
 
167
- def object_info_request(ident, msg)
163
+ def inspect_request(ident, msg)
168
164
  o = @backend.eval(msg[:content]['oname'])
169
165
  content = {
170
166
  oname: msg[:content]['oname'],
@@ -172,18 +168,34 @@ module IRuby
172
168
  ismagic: false,
173
169
  isalias: false,
174
170
  docstring: '', # TODO
175
- type_class: o.class.to_s,
176
171
  type_class: o.class.superclass.to_s,
177
172
  string_form: o.inspect
178
173
  }
179
174
  content[:length] = o.length if o.respond_to?(:length)
180
- @session.send(@reply_socket, 'object_info_reply', content, ident)
175
+ @session.send(:reply, 'inspect_reply', content, ident)
181
176
  rescue Exception
182
177
  content = {
183
178
  oname: msg[:content]['oname'],
184
179
  found: false
185
180
  }
186
- @session.send(@reply_socket, 'object_info_reply', content, ident)
181
+ @session.send(:reply, 'inspect_reply', content, ident)
182
+ end
183
+
184
+ def comm_open(ident, msg)
185
+ comm_id = msg[:content]['comm_id']
186
+ target_name = msg[:content]['target_name']
187
+ target = Comm.targets[target_name]
188
+ @comms[comm_id] = target.new(target_name, comm_id)
189
+ end
190
+
191
+ def comm_msg(ident, msg)
192
+ @comms[msg[:content]['comm_id']].comm_msg(msg[:content]['data'])
193
+ end
194
+
195
+ def comm_close(ident, msg)
196
+ comm_id = msg[:content]['comm_id']
197
+ @comms[comm_id].comm_close
198
+ @comms.delete(comm_id)
187
199
  end
188
200
  end
189
201
  end