summaryrefslogtreecommitdiff
path: root/gemfeed/2025-10-11-key-takeaways-from-the-well-grounded-rubyist.html
blob: 75950fb39ec8c987ef1077208d7a88efdece6100 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Key Takeaways from The Well-Grounded Rubyist</title>
<link rel="shortcut icon" type="image/gif" href="/favicon.ico" />
<link rel="stylesheet" href="../style.css" />
<link rel="stylesheet" href="style-override.css" />
</head>
<body>
<p class="header">
<a href="https://foo.zone">Home</a> | <a href="https://codeberg.org/snonux/foo.zone/src/branch/content-md/gemfeed/2025-10-11-key-takeaways-from-the-well-grounded-rubyist.md">Markdown</a> | <a href="gemini://foo.zone/gemfeed/2025-10-11-key-takeaways-from-the-well-grounded-rubyist.gmi">Gemini</a>
</p>
<h1 style='display: inline' id='key-takeaways-from-the-well-grounded-rubyist'>Key Takeaways from The Well-Grounded Rubyist</h1><br />
<br />
<span class='quote'>Published at 2025-10-11T15:25:14+03:00</span><br />
<br />
<span>Some time ago, I wrote about my journey into Ruby and how "The Well-Grounded Rubyist" helped me to get a better understanding of the language. I took a lot of notes while reading the book, and I think it&#39;s time to share some of them. This is not a comprehensive review, but rather a collection of interesting tidbits and concepts that stuck with me.</span><br />
<br />
<h2 style='display: inline' id='table-of-contents'>Table of Contents</h2><br />
<br />
<ul>
<li><a href='#key-takeaways-from-the-well-grounded-rubyist'>Key Takeaways from The Well-Grounded Rubyist</a></li>
<li>⇢ <a href='#the-object-model'>The Object Model</a></li>
<li>⇢ ⇢ <a href='#everything-is-an-object-almost'>Everything is an object (almost)</a></li>
<li>⇢ ⇢ <a href='#the-self-keyword'>The <span class='inlinecode'>self</span> keyword</a></li>
<li>⇢ ⇢ <a href='#singleton-methods'>Singleton Methods</a></li>
<li>⇢ ⇢ <a href='#classes-are-objects'>Classes are Objects</a></li>
<li>⇢ <a href='#control-flow-and-methods'>Control Flow and Methods</a></li>
<li>⇢ ⇢ <a href='#case-and-the--operator'><span class='inlinecode'>case</span> and the <span class='inlinecode'>===</span> operator</a></li>
<li>⇢ ⇢ <a href='#blocks-and-yield'>Blocks and <span class='inlinecode'>yield</span></a></li>
<li>⇢ <a href='#fun-with-data-types'>Fun with Data Types</a></li>
<li>⇢ ⇢ <a href='#symbols'>Symbols</a></li>
<li>⇢ ⇢ <a href='#arrays-and-hashes'>Arrays and Hashes</a></li>
<li>⇢ <a href='#final-thoughts'>Final Thoughts</a></li>
</ul><br />
<a class='textlink' href='./2021-07-04-the-well-grounded-rubyist.html'>My first post about the book.</a><br />
<br />
<a href='./the-well-grounded-rubyist/book-cover.jpg'><img src='./the-well-grounded-rubyist/book-cover.jpg' /></a><br />
<br />
<h2 style='display: inline' id='the-object-model'>The Object Model</h2><br />
<br />
<span>One of the most fascinating aspects of Ruby is its object model. The book does a great job of explaining the details.</span><br />
<br />
<h3 style='display: inline' id='everything-is-an-object-almost'>Everything is an object (almost)</h3><br />
<br />
<span>In Ruby, most things are objects. This includes numbers, strings, and even classes themselves. This has some interesting consequences. For example, you can&#39;t use <span class='inlinecode'>i++</span> like in C or Java. Integers are immutable objects. <span class='inlinecode'>1</span> is always the same object. <span class='inlinecode'>1 + 1</span> returns a new object, <span class='inlinecode'>2</span>.</span><br />
<br />
<h3 style='display: inline' id='the-self-keyword'>The <span class='inlinecode'>self</span> keyword</h3><br />
<br />
<span>There is always a current object, <span class='inlinecode'>self</span>. If you call a method without an explicit receiver, it&#39;s called on <span class='inlinecode'>self</span>. For example, <span class='inlinecode'>puts "hello"</span> is actually <span class='inlinecode'>self.puts "hello"</span>.</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><i><font color="silver"># At the top level, self is the main object</font></i>
p <b><u><font color="#000000">self</font></u></b>
<i><font color="silver"># =&gt; main</font></i>
p <b><u><font color="#000000">self</font></u></b>.<b><u><font color="#000000">class</font></u></b>
<i><font color="silver"># =&gt; Object</font></i>

<b><u><font color="#000000">def</font></u></b> foo
  <i><font color="silver"># Inside a method, self is the object that received the call</font></i>
  p <b><u><font color="#000000">self</font></u></b>
<b><u><font color="#000000">end</font></u></b>

foo
<i><font color="silver"># =&gt; main</font></i>
</pre>
<br />
<span>This code demonstrates how <span class='inlinecode'>self</span> changes depending on the context. At the top level, it&#39;s <span class='inlinecode'>main</span>, an instance of <span class='inlinecode'>Object</span>. When <span class='inlinecode'>foo</span> is called without a receiver, it&#39;s called on <span class='inlinecode'>main</span>.</span><br />
<br />
<h3 style='display: inline' id='singleton-methods'>Singleton Methods</h3><br />
<br />
<span>You can add methods to individual objects. These are called singleton methods.</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre>obj = <font color="#808080">"a string"</font>

<b><u><font color="#000000">def</font></u></b> obj.shout
  <b><u><font color="#000000">self</font></u></b>.upcase + <font color="#808080">"!"</font>
<b><u><font color="#000000">end</font></u></b>

p obj.shout
<i><font color="silver"># =&gt; "A STRING!"</font></i>

obj2 = <font color="#808080">"another string"</font>
<i><font color="silver"># obj2.shout would raise a NoMethodError</font></i>
</pre>
<br />
<span>Here, the <span class='inlinecode'>shout</span> method is only available on the <span class='inlinecode'>obj</span> object. This is a powerful feature for adding behavior to specific instances.</span><br />
<br />
<h3 style='display: inline' id='classes-are-objects'>Classes are Objects</h3><br />
<br />
<span>Classes themselves are objects, instances of the <span class='inlinecode'>Class</span> class. This means you can create classes dynamically.</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre>MyClass = Class.new <b><u><font color="#000000">do</font></u></b>
  <b><u><font color="#000000">def</font></u></b> say_hello
    puts <font color="#808080">"Hello from a dynamically created class!"</font>
  <b><u><font color="#000000">end</font></u></b>
<b><u><font color="#000000">end</font></u></b>

instance = MyClass.new
instance.say_hello
<i><font color="silver"># =&gt; Hello from a dynamically created class!</font></i>
</pre>
<br />
<span>This shows how to create a new class and assign it to a constant. This is what happens behind the scenes when you use the <span class='inlinecode'>class</span> keyword.</span><br />
<br />
<h2 style='display: inline' id='control-flow-and-methods'>Control Flow and Methods</h2><br />
<br />
<span>The book clarified many things about how methods and control flow work in Ruby.</span><br />
<br />
<h3 style='display: inline' id='case-and-the--operator'><span class='inlinecode'>case</span> and the <span class='inlinecode'>===</span> operator</h3><br />
<br />
<span>The <span class='inlinecode'>case</span> statement is more powerful than I thought. It uses the <span class='inlinecode'>===</span> (threequals or case equality) operator for comparison, not <span class='inlinecode'>==</span>. Different classes can implement <span class='inlinecode'>===</span> in their own way.</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><i><font color="silver"># For ranges, it checks for inclusion</font></i>
p (<font color="#000000">1</font>..<font color="#000000">5</font>) === <font color="#000000">3</font> <i><font color="silver"># =&gt; true</font></i>

<i><font color="silver"># For classes, it checks if the object is an instance of the class</font></i>
p String === <font color="#808080">"hello"</font> <i><font color="silver"># =&gt; true</font></i>

<i><font color="silver"># For regexes, it checks for a match</font></i>
p /llo/ === <font color="#808080">"hello"</font> <i><font color="silver"># =&gt; true</font></i>

<b><u><font color="#000000">def</font></u></b> check(value)
  <b><u><font color="#000000">case</font></u></b> value
  <b><u><font color="#000000">when</font></u></b> String
    <font color="#808080">"It's a string"</font>
  <b><u><font color="#000000">when</font></u></b> (<font color="#000000">1</font>..<font color="#000000">10</font>)
    <font color="#808080">"It's a number between 1 and 10"</font>
  <b><u><font color="#000000">else</font></u></b>
    <font color="#808080">"Something else"</font>
  <b><u><font color="#000000">end</font></u></b>
<b><u><font color="#000000">end</font></u></b>

p check(<font color="#000000">5</font>) <i><font color="silver"># =&gt; "It's a number between 1 and 10"</font></i>
</pre>
<br />
<h3 style='display: inline' id='blocks-and-yield'>Blocks and <span class='inlinecode'>yield</span></h3><br />
<br />
<span>Blocks are a cornerstone of Ruby. You can pass them to methods to customize their behavior. The <span class='inlinecode'>yield</span> keyword is used to call the block.</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><b><u><font color="#000000">def</font></u></b> my_iterator
  puts <font color="#808080">"Entering the method"</font>
  <b><u><font color="#000000">yield</font></u></b>
  puts <font color="#808080">"Back in the method"</font>
  <b><u><font color="#000000">yield</font></u></b>
<b><u><font color="#000000">end</font></u></b>

my_iterator { puts <font color="#808080">"Inside the block"</font> }
<i><font color="silver"># Entering the method</font></i>
<i><font color="silver"># Inside the block</font></i>
<i><font color="silver"># Back in the method</font></i>
<i><font color="silver"># Inside the block</font></i>
</pre>
<br />
<span>This simple iterator shows how <span class='inlinecode'>yield</span> transfers control to the block. You can also pass arguments to <span class='inlinecode'>yield</span> and get a return value from the block.</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><b><u><font color="#000000">def</font></u></b> with_return
  result = <b><u><font color="#000000">yield</font></u></b>(<font color="#000000">5</font>)
  puts <font color="#808080">"The block returned #{result}"</font>
<b><u><font color="#000000">end</font></u></b>

with_return { |n| n * <font color="#000000">2</font> }
<i><font color="silver"># =&gt; The block returned 10</font></i>
</pre>
<br />
<span>This demonstrates passing an argument to the block and using its return value.</span><br />
<br />
<h2 style='display: inline' id='fun-with-data-types'>Fun with Data Types</h2><br />
<br />
<span>Ruby&#39;s core data types are full of nice little features.</span><br />
<br />
<h3 style='display: inline' id='symbols'>Symbols</h3><br />
<br />
<span>Symbols are like immutable strings. They are great for keys in hashes because they are unique and memory-efficient.</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><i><font color="silver"># Two strings with the same content are different objects</font></i>
p <font color="#808080">"foo"</font>.object_id
p <font color="#808080">"foo"</font>.object_id

<i><font color="silver"># Two symbols with the same content are the same object</font></i>
p :foo.object_id
p :foo.object_id

<i><font color="silver"># Modern hash syntax uses symbols as keys</font></i>
my_hash = { name: <font color="#808080">"Paul"</font>, language: <font color="#808080">"Ruby"</font> }
p my_hash[:name] <i><font color="silver"># =&gt; "Paul"</font></i>
</pre>
<br />
<span>This code highlights the difference between strings and symbols and shows the convenient hash syntax.</span><br />
<br />
<h3 style='display: inline' id='arrays-and-hashes'>Arrays and Hashes</h3><br />
<br />
<span>Arrays and hashes have a rich API. The <span class='inlinecode'>%w</span> and <span class='inlinecode'>%i</span> shortcuts for creating arrays of strings and symbols are very handy.</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre><i><font color="silver"># Array of strings</font></i>
p %w[one two three]
<i><font color="silver"># =&gt; ["one", "two", "three"]</font></i>

<i><font color="silver"># Array of symbols</font></i>
p %i[one two three]
<i><font color="silver"># =&gt; [:one, :two, :three]</font></i>
</pre>
<br />
<span>A quick way to create arrays. You can also retrieve multiple values at once.</span><br />
<br />
<!-- Generator: GNU source-highlight 3.1.9
by Lorenzo Bettini
http://www.lorenzobettini.it
http://www.gnu.org/software/src-highlite -->
<pre>arr = [<font color="#000000">10</font>, <font color="#000000">20</font>, <font color="#000000">30</font>, <font color="#000000">40</font>, <font color="#000000">50</font>]
p arr.values_at(<font color="#000000">0</font>, <font color="#000000">2</font>, <font color="#000000">4</font>)
<i><font color="silver"># =&gt; [10, 30, 50]</font></i>

hash = { a: <font color="#000000">1</font>, b: <font color="#000000">2</font>, c: <font color="#000000">3</font> }
p hash.values_at(:a, :c)
<i><font color="silver"># =&gt; [1, 3]</font></i>
</pre>
<br />
<span>The <span class='inlinecode'>values_at</span> method is a concise way to get multiple elements.</span><br />
<br />
<h2 style='display: inline' id='final-thoughts'>Final Thoughts</h2><br />
<br />
<span>These are just a few of the many things I learned from "The Well-Grounded Rubyist". The book gave me a much deeper appreciation for the language and its design. If you are a Ruby programmer, I highly recommend it. Meanwhile, I also read the book "Programming Ruby 3.3", just I didn&#39;t have time to process my notes there yet. </span><br />
<br />
<span>E-Mail your comments to <span class='inlinecode'>paul@nospam.buetow.org</span> :-)</span><br />
<br />
<span>Other Ruby-related posts:</span><br />
<br />
<a class='textlink' href='./2025-10-11-key-takeaways-from-the-well-grounded-rubyist.html'>2025-10-11 Key Takeaways from The Well-Grounded Rubyist (You are currently reading this)</a><br />
<a class='textlink' href='./2021-07-04-the-well-grounded-rubyist.html'>2021-07-04 The Well-Grounded Rubyist</a><br />
<br />
<a class='textlink' href='../'>Back to the main site</a><br />
<p class="footer">
	Generated with <a href="https://codeberg.org/snonux/gemtexter">Gemtexter 3.0.1-develop</a> |
	served by <a href="https://www.OpenBSD.org">OpenBSD</a>/<a href="https://man.openbsd.org/relayd.8">relayd(8)</a>+<a href="https://man.openbsd.org/httpd.8">httpd(8)</a> |
	<a href="https://foo.zone/site-mirrors.html">Site Mirrors</a>
	<br />
	Webring: <a href="https://shring.sh/foo.zone/previous">previous</a> | <a href="https://shring.sh">shring</a> | <a href="https://shring.sh/foo.zone/next">next</a>
</p>
</body>
</html>