iruby 0.1.13 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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