Skip to content

Commit 5c69263

Browse files
authored
Merge pull request #744 from russtoku/ruby-client
Add Ruby client
2 parents 67e1c4f + 3c3ff48 commit 5c69263

File tree

8 files changed

+968
-4
lines changed

8 files changed

+968
-4
lines changed

README.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ The core features of Conjure are language agnostic (although it's targeted at Li
2929
* JavaScript (using https://nodejs.org/[Node.js]) over stdio
3030
* https://ccrma.stanford.edu/software/snd/[Snd] / https://ccrma.stanford.edu/software/snd/snd/s7.html[s7] (sound editor scriptable with Scheme) over stdio
3131
* https://en.wikipedia.org/wiki/SQL[SQL] (PostgreSQL psql by default) over stdio
32+
* https://www.ruby-lang.org/en/[Ruby] (using https://ruby.github.io/irb/[irb]) over stdio
3233

3334
You can learn more about the mappings and configuration inside Neovim with `:help conjure`. Each language client also has it's own specific help text under `:help conjure-client-{LANGUAGE}-{TRANSPORT}`, such as `:help conjure-client-clojure-nrepl`, which contains specific mappings and configuration for that client.
3435

dev/ruby/sandbox.rb

Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
# Should be able to evaluate all statements.
2+
3+
# From https://www.ruby-lang.org/en/about/
4+
# - Seeing Everything as an Object
5+
5.times { print "We *love* Ruby -- it's outrageous!" }
6+
7+
# This should result in an error; undefined method 'plus'
8+
5.plus 3
9+
10+
5+ 3 # 8
11+
5 + 3 # 8
12+
13+
# form-node? can handle nested binary expressions but you must put
14+
# your cursor on the right-most number or operator.
15+
5 + 4 + 3 + 2 + 1 # 15
16+
0.5 + 4 + 3 + 2 + 1 # 10.5
17+
18+
2 * 7 / 3 + 9 # 13
19+
20+
x = 2 * 7 / 3 + 9 # (out) x = 2 * 7 / 3 + 9
21+
# => 13
22+
puts 2 * 7 / 3 + 9
23+
24+
25+
aNum = Numeric.new
26+
27+
# This should result in an error; undefined method '+'
28+
aNum + 2
29+
30+
# After assignment, the '+' method is available.
31+
aNum = 2 # 2
32+
33+
aNum + 2.0 # 4.0
34+
aNum + 2 # 4
35+
36+
# - Ruby’s Flexibility
37+
# Add a new method to an existing class.
38+
class Numeric
39+
def plus(x)
40+
self.+(x)
41+
end
42+
end # :plus
43+
44+
# 'plus' and '+' are methods of a Numeric.
45+
y = 5.plus 6
46+
5.plus 6 # 11
47+
5.+ 6 # 11
48+
49+
# form-node? recognizes the arguments of a function.
50+
6 * 17.2 / 0.2 # 515.9999999999999
51+
y = 5.plus 6 * 17.2 / 0.2
52+
# y = 520.9999999999999
53+
54+
aNum
55+
# => 2
56+
aNum.plus 3 # 5
57+
58+
# - Blocks: a Truly Expressive Feature
59+
search_engines =
60+
%w[Google Yahoo MSN].map do |engine|
61+
"http://www." + engine.downcase + ".com"
62+
end
63+
# search_engines = ["http://www.google.com", "http://www.yahoo.com", "http://www.msn.com"]
64+
65+
# - Ruby and the Mixin
66+
# Modules are collections of methods.
67+
class MyArray
68+
end
69+
70+
MyArray.methods()
71+
# [:allocate,
72+
# :superclass,
73+
# :subclasses,
74+
# :attached_object,
75+
# ...
76+
# :!=,
77+
# :__id__,
78+
# :instance_eval,
79+
# :instance_exec]
80+
MyArray.methods(false) # []
81+
82+
MyArray.instance_methods()
83+
# [:pretty_print_cycle,
84+
# :pretty_print_instance_variables,
85+
# :pretty_print_inspect,
86+
# ...
87+
# :!=,
88+
# :__id__,
89+
# :instance_eval,
90+
# :instance_exec]
91+
MyArray.instance_methods(false) # []
92+
93+
# Mixin some stuff.
94+
class MyArray
95+
include Enumerable
96+
end
97+
98+
# Can we tell how many methods are added when we include from mixin?
99+
Enumerable.methods(false) # []
100+
Enumerable.instance_methods(false)
101+
# [:drop,
102+
# :drop_while,
103+
# :cycle,
104+
# ...
105+
# :zip,
106+
# :take,
107+
# :take_while]
108+
109+
MyArray.methods()
110+
# [:allocate,
111+
# :superclass,
112+
# :subclasses,
113+
# ...
114+
# :!=,
115+
# :__id__,
116+
# :instance_eval,
117+
# :instance_exec]
118+
MyArray.methods(false) # []
119+
MyArray.instance_methods()
120+
# [:drop,
121+
# :drop_while,
122+
# :cycle,
123+
# ...
124+
# :zip,
125+
# :take,
126+
# :take_while, <<--- From here and above are from Enumerable.
127+
# :pretty_print_cycle,
128+
# :pretty_print_instance_variables,
129+
# :pretty_print_inspect,
130+
# ...
131+
# :!=,
132+
# :__id__,
133+
# :instance_eval,
134+
# :instance_exec]
135+
MyArray.instance_methods(false) # []
136+
137+
# End of From https://www.ruby-lang.org/en/about/
138+
139+
140+
# Incorrect array expression
141+
3 4 5]
142+
# => (error) <internal:kernel>:168:in 'Kernel#loop': (irb):89: syntax errors found (SyntaxError)
143+
144+
[3 4 5]
145+
# => (error) <internal:kernel>:168:in 'Kernel#loop': (irb):90: syntax errors found (SyntaxError)
146+
147+
# Correct array expression
148+
[3, 4, 5] # [3, 4, 5]
149+
150+
151+
# Block comments
152+
# - https://docs.ruby-lang.org/en/master/syntax/comments_rdoc.html
153+
=begin
154+
This is commented out.
155+
156+
class Foo
157+
end
158+
159+
=end
160+
161+
# =begin and =end can not be indented, so this is a syntax error:
162+
class Foo
163+
=begin
164+
Will not work
165+
=end
166+
end
167+
168+
# frozen strings
169+
# https://stackoverflow.com/a/37799399
170+
# `# frozen_string_literal: true` is supposed to make all string literals frozen.
171+
# This works only if the magic comment is in the first comment section of a file.
172+
var = 'hello'
173+
var.frozen? # false
174+
var.freeze()
175+
var.frozen? # true
176+
var << " not" # (error) (irb):29:in '<main>': can't modify frozen String: "hello" (FrozenError)
177+
178+
var2 = -var
179+
var2.frozen? # true
180+
var2 << " not" # (error) (irb):111:in '<main>': can't modify frozen String: "hello" (FrozenError)
181+
182+
var3 = +var
183+
var3.frozen? # false
184+
var3 << " not" # "hello not"
185+
186+
187+
# From Ruby in Twenty Minutes
188+
# - https://www.ruby-lang.org/en/documentation/quickstart/
189+
190+
puts "Hello World"
191+
192+
3 ** 2
193+
194+
Math.sqrt(9)
195+
196+
a = 3 ** 2
197+
b = 4 ** 2
198+
Math.sqrt(a+b)
199+
200+
def hi
201+
puts "Hello World!"
202+
end
203+
204+
# - The Brief, Repetitive Lives of a Method
205+
hi # eval word or selection
206+
207+
hi() # eval current-form
208+
209+
def hi(name)
210+
puts "Hello #{name}!"
211+
end
212+
213+
hi("Matz")
214+
215+
# - Holding Spots in a String
216+
def hi(name = "World")
217+
puts "Hello #{name.capitalize}!"
218+
end
219+
220+
# Eval these with selections:
221+
hi "chris"
222+
# (out) hi "chris"
223+
224+
hi
225+
# (out) Hello World!
226+
227+
# - Evolving Into a Greeter
228+
class Greeter
229+
def initialize(name = "World")
230+
@name = name
231+
end
232+
def say_hi
233+
puts "Hi #{@name}!"
234+
end
235+
def say_bye
236+
puts "bye #{@name}, come back soon."
237+
end
238+
end
239+
240+
greeter = Greeter.new("Pat")
241+
greeter.say_hi
242+
greeter.say_bye
243+
# This should be an error.
244+
greeter.@name
245+
246+
# - Under the Object’s Skin
247+
Greeter.instance_methods
248+
Greeter.instance_methods()
249+
250+
Greeter.instance_methods(false) # [:say_hi, :say_bye]
251+
252+
greeter.respond_to?("name") # false
253+
greeter.respond_to?("say_hi") # true
254+
greeter.respond_to?("to_s") # true
255+
256+
# - Altering Classes—It’s Never Too Late
257+
class Greeter
258+
attr_accessor :name
259+
end
260+
261+
greeter = Greeter.new("Andy")
262+
# Access attribute
263+
greeter.respond_to?("name") # true
264+
# Set attribute
265+
greeter.respond_to?("name=") # true
266+
# Same as when evaluated with "()".
267+
greeter.say_hi
268+
# This should update the name attribute.
269+
greeter.name="Betty"
270+
greeter
271+
greeter.name
272+
greeter.say_hi
273+
274+
# - Cycling and Looping—a.k.a. Iteration
275+
class MegaGreeter
276+
attr_accessor :names
277+
278+
# Create the object
279+
def initialize(names = "World")
280+
@names = names
281+
end
282+
283+
# Say hi to everybody
284+
def say_hi
285+
if @names.nil?
286+
puts "..."
287+
elsif @names.respond_to?("each")
288+
# @names is a list of some kind, iterate!
289+
@names.each do |name|
290+
puts "Hello #{name}!"
291+
end
292+
else
293+
puts "Hello #{@names}!"
294+
end
295+
end
296+
297+
# Say bye to everybody
298+
def say_bye
299+
if @names.nil?
300+
puts "..."
301+
elsif @names.respond_to?("join")
302+
# Join the list elements with commas
303+
puts "Goodbye #{@names.join(", ")}. Come back soon!"
304+
else
305+
puts "Goodbye #{@names}. Come back soon!"
306+
end
307+
end
308+
end
309+
310+
mg = MegaGreeter.new
311+
312+
# Evaluate with selection:
313+
mg.say_hi
314+
# (out) Hello World!
315+
# => nil
316+
317+
mg.say_bye
318+
# (out) Goodbye World. Come back soon!
319+
# => nil
320+
321+
mg.names # "World"
322+
mg.names.respond_to?("each") # false
323+
mg.names.respond_to?("join") # false
324+
325+
# Change the name to an array of names
326+
mg.names = ["Albert", "Brenda", "Charles", "Dave", "Engelbert"]
327+
328+
# Evaluate with selection:
329+
mg.say_hi
330+
# (out) Hello Albert!↵Hello Brenda!↵Hello Charles!↵Hello Dave!↵Hello Engelbert!
331+
# => ["Albert", "Brenda", "Charles", "Dave", "Engelbert"]
332+
#
333+
mg.say_bye
334+
# (out) Goodbye Albert, Brenda, Charles, Dave, Engelbert. Come back soon!
335+
# => nil
336+

0 commit comments

Comments
 (0)