Class: Nrepl::Repl
- Inherits:
-
Object
- Object
- Nrepl::Repl
- Defined in:
- lib/nrepl/repl.rb
Instance Attribute Summary collapse
-
#debug ⇒ Object
Returns the value of attribute debug.
-
#session ⇒ Object
Returns the value of attribute session.
Class Method Summary collapse
-
.connect(port) ⇒ Nrepl::Repl
Connects to an already running nrepl server.
-
.start(port = nil) ⇒ Nrepl::Repl
Starts a new clojure process at the current working directory.
Instance Method Summary collapse
-
#clone_session(session = nil) ⇒ String
Clones the bindings for the provided session and sets the new session to current.
-
#close_session(session = nil) ⇒ Object
Closes the provided sessions.
- #debug! ⇒ Object
-
#eval(code, &block) ⇒ Object
Evaluates code on the repl, returning an array of responses.
- #get_socket(tries = 3) ⇒ Object
-
#initialize(port) ⇒ Repl
constructor
A new instance of Repl.
-
#list_sessions ⇒ <String>
Returns a list of sessions known to the repl.
-
#running? ⇒ Boolean
Returns true if we can get a socket connection to this repl.
-
#send(command) ⇒ Object
Sends a raw command to the repl, returning an array of responses.
Constructor Details
#initialize(port) ⇒ Repl
Returns a new instance of Repl.
55 56 57 58 59 |
# File 'lib/nrepl/repl.rb', line 55 def initialize(port) @port = port @session = nil @debug = false end |
Instance Attribute Details
#debug ⇒ Object
Returns the value of attribute debug.
9 10 11 |
# File 'lib/nrepl/repl.rb', line 9 def debug @debug end |
#session ⇒ Object
Returns the value of attribute session.
8 9 10 |
# File 'lib/nrepl/repl.rb', line 8 def session @session end |
Class Method Details
.connect(port) ⇒ Nrepl::Repl
Connects to an already running nrepl server
16 17 18 |
# File 'lib/nrepl/repl.rb', line 16 def self.connect(port) new(port) end |
.start(port = nil) ⇒ Nrepl::Repl
Starts a new clojure process at the current working directory
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 |
# File 'lib/nrepl/repl.rb', line 26 def self.start(port=nil) read, write = IO.pipe pid = fork do read.close Process.setsid STDOUT.reopen write STDERR.reopen write STDIN.reopen "/dev/null", "r" exec "bash -c 'lein repl :headless :port #{port}'" end write.close line = read.gets case line when /Address already in use/ ; # no-op, just connect to existing repl when /nREPL server started on port (\d+)/ port = $~[1].to_i else raise "Unknown error launching repl: #{line}" Process.kill(pid) Process.waitpid(pid) end read.close new(port) end |
Instance Method Details
#clone_session(session = nil) ⇒ String
Clones the bindings for the provided session and sets the new session to current
80 81 82 83 84 |
# File 'lib/nrepl/repl.rb', line 80 def clone_session(session=nil) response = send(op:"clone", session:session).first @session = response["new-session"] @session end |
#close_session(session = nil) ⇒ Object
Closes the provided sessions
91 92 93 |
# File 'lib/nrepl/repl.rb', line 91 def close_session(session=nil) result = send(op:"close", session:session) end |
#debug! ⇒ Object
61 62 63 64 |
# File 'lib/nrepl/repl.rb', line 61 def debug! @debug = true self end |
#eval(code, &block) ⇒ Object
Evaluates code on the repl, returning an array of responses
108 109 110 |
# File 'lib/nrepl/repl.rb', line 108 def eval(code, &block) result = send(op:"eval", code:code, &block) end |
#get_socket(tries = 3) ⇒ Object
150 151 152 153 154 155 156 |
# File 'lib/nrepl/repl.rb', line 150 def get_socket(tries = 3) retriable on: [Errno::ECONNREFUSED], tries: tries, interval: 3 do TCPSocket.new("localhost", @port) end rescue Errno::ECONNREFUSED nil end |
#list_sessions ⇒ <String>
Returns a list of sessions known to the repl
99 100 101 102 |
# File 'lib/nrepl/repl.rb', line 99 def list_sessions response = send(op:"ls-sessions").first response["sessions"] end |
#running? ⇒ Boolean
Returns true if we can get a socket connection to this repl
70 71 72 |
# File 'lib/nrepl/repl.rb', line 70 def running? !!get_socket(0) end |
#send(command) ⇒ Object
Sends a raw command to the repl, returning an array of responses
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/nrepl/repl.rb', line 115 def send(command) command = command.reverse_merge(session: @session).delete_blank sock = get_socket sock.print command.bencode puts ">>> #{command.inspect}" if @debug responses = [] done = false begin until done retriable timeout: 0.2, tries: 100 do raw = sock.recv(100000) #TODO: figure out better way to ensure we've drained the receive buffer besides large magic number decoded = raw.bdecode puts "<<< #{decoded}" if @debug responses << decoded yield decoded if block_given? status = responses.last["status"] done = status.include?("done") || status.include?("error") end end rescue BEncode::DecodeError # TODO end responses end |