Skip to content

Commit a9f9809

Browse files
committed
Add 'return' keyword
1 parent ec0dedd commit a9f9809

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

lib/ruby_lsp/listeners/hover.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class Hover
3434
Prism::ModuleNode,
3535
Prism::NextNode,
3636
Prism::RescueNode,
37+
Prism::ReturnNode,
3738
Prism::SymbolNode,
3839
Prism::StringNode,
3940
Prism::InterpolatedStringNode,
@@ -92,6 +93,7 @@ def initialize(response_builder, global_state, uri, node_context, dispatcher, so
9293
:on_module_node_enter,
9394
:on_next_node_enter,
9495
:on_rescue_node_enter,
96+
:on_return_node_enter,
9597
:on_super_node_enter,
9698
:on_forwarding_super_node_enter,
9799
:on_string_node_enter,
@@ -174,6 +176,11 @@ def on_rescue_node_enter(node)
174176
handle_keyword_documentation(node.keyword)
175177
end
176178

179+
#: (Prism::ReturnNode node) -> void
180+
def on_return_node_enter(node)
181+
handle_keyword_documentation(node.keyword)
182+
end
183+
177184
#: (Prism::InterpolatedStringNode node) -> void
178185
def on_interpolated_string_node_enter(node)
179186
generate_heredoc_hover(node)

lib/ruby_lsp/static_docs.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ module RubyLsp
2525
"module" => "Defines a module",
2626
"next" => "Skips the rest of the current iteration and moves to the next iteration of a loop or block",
2727
"rescue" => "Handles exceptions that occur in the code block",
28+
"return" => "Exits a method and returns a value",
2829
"yield" => "Invokes the passed block with the given arguments",
2930
}.freeze #: Hash[String, String]
3031
end

static_docs/return.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Return
2+
3+
In Ruby, `return` is used to explicitly return a value from a method or block. While Ruby automatically returns the value of the last evaluated expression, `return` allows you to exit the method early and specify the return value.
4+
5+
```ruby
6+
def greet(name)
7+
return "Hello, #{name}!"
8+
end
9+
10+
puts greet("Ruby") # => "Hello, Ruby!"
11+
```
12+
13+
When no value is provided to `return`, it returns `nil`:
14+
15+
```ruby
16+
def early_exit
17+
return if condition?
18+
# Code here won't execute if condition? is true
19+
perform_task
20+
end
21+
```
22+
23+
## Multiple values
24+
25+
Ruby allows returning multiple values, which are automatically converted into an array:
26+
27+
```ruby
28+
def calculate_stats(numbers)
29+
sum = numbers.sum
30+
average = sum / numbers.length.to_f
31+
return sum, average
32+
end
33+
34+
total, mean = calculate_stats([1, 2, 3, 4])
35+
puts total # => 10
36+
puts mean # => 2.5
37+
```
38+
39+
## Early returns
40+
41+
Using `return` for early exits can help make code more readable by reducing nesting:
42+
43+
```ruby
44+
# Without early return
45+
def process_user(user)
46+
if user.active?
47+
if user.admin?
48+
perform_admin_task
49+
else
50+
perform_regular_task
51+
end
52+
else
53+
puts "Inactive user"
54+
end
55+
end
56+
57+
# With early return
58+
def process_user(user)
59+
return puts "Inactive user" unless user.active?
60+
return perform_admin_task if user.admin?
61+
perform_regular_task
62+
end
63+
```
64+
65+
## Return in blocks
66+
67+
When used inside a block, `return` will exit from the method that yielded to the block:
68+
69+
```ruby
70+
def process_items
71+
[1, 2, 3].each do |item|
72+
return item if item > 1
73+
puts "Processing #{item}"
74+
end
75+
puts "Done processing"
76+
end
77+
78+
result = process_items
79+
# Prints "Processing 1"
80+
puts result # => 2
81+
```
82+
83+
## Return in procs vs lambdas
84+
85+
The behavior of `return` differs between procs and lambdas:
86+
87+
```ruby
88+
# In a proc, return exits the enclosing method
89+
def proc_return
90+
proc = Proc.new { return "From proc" }
91+
proc.call
92+
"From method" # Never reached
93+
end
94+
95+
puts proc_return # => "From proc"
96+
97+
# In a lambda, return only exits the lambda itself
98+
def lambda_return
99+
lambda = -> { return "From lambda" }
100+
lambda.call
101+
"From method" # This is reached
102+
end
103+
104+
puts lambda_return # => "From method"
105+
```
106+
107+
When using `return`, consider:
108+
- Whether an implicit return would be clearer
109+
- If early returns improve code readability
110+
- The context (proc vs lambda) when using `return` in blocks
111+
- Using multiple returns judiciously

0 commit comments

Comments
 (0)