summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <git@mx.buetow.org>2021-07-04 14:34:12 +0100
committerPaul Buetow <git@mx.buetow.org>2021-07-04 14:34:12 +0100
commit24f18d6d9f4a7d2cf01717ea71f21e77436924e9 (patch)
treee4a85ad5d4c19aeaecf57c5ea729acde9ab1193e
parent5954326f4d7bd39a8f1155fa7f2fbf94a8a2498d (diff)
add the well grounded rubyist
-rw-r--r--contact-information.html4
-rw-r--r--gemfeed/2008-06-26-perl-poetry.html4
-rw-r--r--gemfeed/2010-04-09-standard-ml-and-haskell.html4
-rw-r--r--gemfeed/2010-05-07-lazy-evaluation-with-standarn-ml.html4
-rw-r--r--gemfeed/2010-05-09-the-fype-programming-language.html4
-rw-r--r--gemfeed/2011-05-07-perl-daemon-service-framework.html4
-rw-r--r--gemfeed/2014-03-24-the-fibonacci.pl.c-polyglot.html4
-rw-r--r--gemfeed/2015-12-05-run-debian-on-your-phone-with-debroid.html4
-rw-r--r--gemfeed/2016-04-03-offsite-backup-with-zfs.html4
-rw-r--r--gemfeed/2016-04-09-jails-and-zfs-on-freebsd-with-puppet.html4
-rw-r--r--gemfeed/2016-04-16-offsite-backup-with-zfs-part2.html4
-rw-r--r--gemfeed/2016-05-22-spinning-up-my-own-authoritative-dns-servers.html4
-rw-r--r--gemfeed/2016-11-20-methods-in-c.html4
-rw-r--r--gemfeed/2018-06-01-realistic-load-testing-with-ioriot-for-linux.html4
-rw-r--r--gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.html4
-rw-r--r--gemfeed/2021-04-24-welcome-to-the-geminispace.html4
-rw-r--r--gemfeed/2021-05-16-personal-bash-coding-style-guide.html4
-rw-r--r--gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.html4
-rw-r--r--gemfeed/2021-07-04-the-well-grounded-rubyist.html133
-rw-r--r--gemfeed/2021-07-04-the-well-grounded-rubyist/book-backside.jpgbin0 -> 179996 bytes
-rw-r--r--gemfeed/2021-07-04-the-well-grounded-rubyist/book-cover.jpgbin0 -> 140259 bytes
-rw-r--r--gemfeed/atom.xml83
-rw-r--r--gemfeed/index.html5
-rw-r--r--index.html5
-rw-r--r--resources.html57
25 files changed, 287 insertions, 68 deletions
diff --git a/contact-information.html b/contact-information.html
index f7389dcb..870b7cc6 100644
--- a/contact-information.html
+++ b/contact-information.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2008-06-26-perl-poetry.html b/gemfeed/2008-06-26-perl-poetry.html
index 49562768..e0fd085f 100644
--- a/gemfeed/2008-06-26-perl-poetry.html
+++ b/gemfeed/2008-06-26-perl-poetry.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2010-04-09-standard-ml-and-haskell.html b/gemfeed/2010-04-09-standard-ml-and-haskell.html
index ae5e5480..936b715b 100644
--- a/gemfeed/2010-04-09-standard-ml-and-haskell.html
+++ b/gemfeed/2010-04-09-standard-ml-and-haskell.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2010-05-07-lazy-evaluation-with-standarn-ml.html b/gemfeed/2010-05-07-lazy-evaluation-with-standarn-ml.html
index 2adf09f6..0052f420 100644
--- a/gemfeed/2010-05-07-lazy-evaluation-with-standarn-ml.html
+++ b/gemfeed/2010-05-07-lazy-evaluation-with-standarn-ml.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2010-05-09-the-fype-programming-language.html b/gemfeed/2010-05-09-the-fype-programming-language.html
index 65803b43..d9bebd88 100644
--- a/gemfeed/2010-05-09-the-fype-programming-language.html
+++ b/gemfeed/2010-05-09-the-fype-programming-language.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2011-05-07-perl-daemon-service-framework.html b/gemfeed/2011-05-07-perl-daemon-service-framework.html
index b1f104ed..22691a8d 100644
--- a/gemfeed/2011-05-07-perl-daemon-service-framework.html
+++ b/gemfeed/2011-05-07-perl-daemon-service-framework.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2014-03-24-the-fibonacci.pl.c-polyglot.html b/gemfeed/2014-03-24-the-fibonacci.pl.c-polyglot.html
index b53a0cb4..72dae7a3 100644
--- a/gemfeed/2014-03-24-the-fibonacci.pl.c-polyglot.html
+++ b/gemfeed/2014-03-24-the-fibonacci.pl.c-polyglot.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2015-12-05-run-debian-on-your-phone-with-debroid.html b/gemfeed/2015-12-05-run-debian-on-your-phone-with-debroid.html
index 94d8c5d6..220414c2 100644
--- a/gemfeed/2015-12-05-run-debian-on-your-phone-with-debroid.html
+++ b/gemfeed/2015-12-05-run-debian-on-your-phone-with-debroid.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2016-04-03-offsite-backup-with-zfs.html b/gemfeed/2016-04-03-offsite-backup-with-zfs.html
index eaf1de89..9bcd9d5c 100644
--- a/gemfeed/2016-04-03-offsite-backup-with-zfs.html
+++ b/gemfeed/2016-04-03-offsite-backup-with-zfs.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2016-04-09-jails-and-zfs-on-freebsd-with-puppet.html b/gemfeed/2016-04-09-jails-and-zfs-on-freebsd-with-puppet.html
index dbf86a9f..8cad2600 100644
--- a/gemfeed/2016-04-09-jails-and-zfs-on-freebsd-with-puppet.html
+++ b/gemfeed/2016-04-09-jails-and-zfs-on-freebsd-with-puppet.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2016-04-16-offsite-backup-with-zfs-part2.html b/gemfeed/2016-04-16-offsite-backup-with-zfs-part2.html
index 0864224a..e8f7aff0 100644
--- a/gemfeed/2016-04-16-offsite-backup-with-zfs-part2.html
+++ b/gemfeed/2016-04-16-offsite-backup-with-zfs-part2.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2016-05-22-spinning-up-my-own-authoritative-dns-servers.html b/gemfeed/2016-05-22-spinning-up-my-own-authoritative-dns-servers.html
index b4e91a51..fd162873 100644
--- a/gemfeed/2016-05-22-spinning-up-my-own-authoritative-dns-servers.html
+++ b/gemfeed/2016-05-22-spinning-up-my-own-authoritative-dns-servers.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2016-11-20-methods-in-c.html b/gemfeed/2016-11-20-methods-in-c.html
index 3d034d9c..7e7e18cf 100644
--- a/gemfeed/2016-11-20-methods-in-c.html
+++ b/gemfeed/2016-11-20-methods-in-c.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2018-06-01-realistic-load-testing-with-ioriot-for-linux.html b/gemfeed/2018-06-01-realistic-load-testing-with-ioriot-for-linux.html
index 22a04619..b5bec980 100644
--- a/gemfeed/2018-06-01-realistic-load-testing-with-ioriot-for-linux.html
+++ b/gemfeed/2018-06-01-realistic-load-testing-with-ioriot-for-linux.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.html b/gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.html
index 63424869..e225dab5 100644
--- a/gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.html
+++ b/gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2021-04-24-welcome-to-the-geminispace.html b/gemfeed/2021-04-24-welcome-to-the-geminispace.html
index d5b02788..6cdb77be 100644
--- a/gemfeed/2021-04-24-welcome-to-the-geminispace.html
+++ b/gemfeed/2021-04-24-welcome-to-the-geminispace.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2021-05-16-personal-bash-coding-style-guide.html b/gemfeed/2021-05-16-personal-bash-coding-style-guide.html
index 96e21701..39726389 100644
--- a/gemfeed/2021-05-16-personal-bash-coding-style-guide.html
+++ b/gemfeed/2021-05-16-personal-bash-coding-style-guide.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.html b/gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.html
index 7f6ec48f..aca21a54 100644
--- a/gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.html
+++ b/gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
diff --git a/gemfeed/2021-07-04-the-well-grounded-rubyist.html b/gemfeed/2021-07-04-the-well-grounded-rubyist.html
new file mode 100644
index 00000000..220d4b83
--- /dev/null
+++ b/gemfeed/2021-07-04-the-well-grounded-rubyist.html
@@ -0,0 +1,133 @@
+<!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>The Well-Grounded Rubyist</title>
+<link rel="shortcut icon" type="image/gif" href="/favicon.ico" />
+<style type="text/css">
+body {
+ margin: auto;
+ padding-left: 10px;
+ padding-right: 10px;
+ max-width: 900px;
+ font-family: sans-serif;
+ font-size: 18px;
+ background-color: #222;
+ color: #ffffef;
+}
+
+a {
+ color: #0ca;
+ text-decoration: none;
+}
+
+a:hover {
+ color: #c0f;
+ text-decoration: none;
+}
+
+img {
+ max-width: 600px;
+ max-height: 400px;
+ display: block;
+ margin: auto;
+}
+
+pre {
+ display: block;
+ background-color: #111;
+ color: #66cdaa;
+ padding: 5px;
+ overflow-x: auto;
+}
+
+a.textlink:before {
+ content: " ⇒ ";
+ padding-left: 2px;
+}
+
+p.quote {
+ color: #82eefd;
+}
+
+p.quote:before {
+ content: " « ";
+ padding-left: 2px;
+}
+
+p.quote:after {
+ content: " » ";
+ padding-right: 2px;
+}
+</style>
+</head>
+<body>
+<h1>The Well-Grounded Rubyist</h1>
+<p class="quote"><i>Written by Paul Buetow 2021-07-04</i></p>
+<p>When I was a Linux System Administrator, I have been programming in Perl for years. I still maintain some personal Perl programming projects (e.g. Xerl, guprecords, Loadbars). After switching jobs a couple of years ago (becoming a Site Reliability Engineer), I found Ruby (and some Python) widely used there. As I wanted to do something new, I decided to give Ruby a go.</p>
+<p>You should learn or try out one new programming language once yearly anyway. If you end up not using the new language, that's not a problem. You will learn new techniques with each new programming language and this also helps you to improve your overall programming skills even for other languages. Also, having some background in a similar programming language makes it reasonably easy to get started. Besides that, learning a new programming language is kick-a** fun!</p>
+<a href="./2021-07-04-the-well-grounded-rubyist/book-cover.jpg"><img src="./2021-07-04-the-well-grounded-rubyist/book-cover.jpg" /></a><br />
+<p>Superficially, Perl seems to have many similarities to Ruby (but, of course, it is entirely different to Perl when you look closer), which pushed me towards Ruby instead of Python. I have tried Python a couple of times before, and I managed to write good code, but I never felt satisfied with the language. I didn't love the syntax, especially the indentations used; they always confused me. I don't dislike Python, but I don't prefer to program in it if I have a choice, especially when there are more propelling alternatives available. Personally, it's so much more fun to program in Ruby than in Python.</p>
+<a href="./2021-07-04-the-well-grounded-rubyist/book-backside.jpg"><img src="./2021-07-04-the-well-grounded-rubyist/book-backside.jpg" /></a><br />
+<p>Yukihiro Matsumoto, inventor of Ruby said: "I wanted a scripting language that was more powerful than Perl and more object-oriented than Python" - So I can see where some of the similarities come from. I personally don't believe that Ruby is more powerful than Perl, though, especially when you take CPAN and/or Perl 6 (now known as Raku) into the equation. Well, it all depends on what you mean with "more powerful". But I want to stay pragmatic and use what's already used at my workplace.</p>
+<h2>My Ruby problem domain</h2>
+<p>I wrote a lot of Ruby code over the last couple of years. There were many small to medium-sized tools and other projects such as Nagios monitoring checks, even an internal monitoring &amp; reporting site based on Sinatra. All Ruby scripts I wrote do their work well; I didn't encounter any significant problems using Ruby for any of these tasks. Of course, there's nothing that couldn't be written in Perl (or Python), though, after all, these languages are all Turing-complete and all these languages also come with a huge set of 3rd party libraries :-).</p>
+<p>I don't use Ruby for all programming projects, though. </p>
+<ul>
+<li>I am using Bash for small sized (usually below 500 lines of code) scripts and ad-hoc command-line automation.</li>
+<li>I program in Google Go for more complex tools (such as DTail) and for problem solving involving data crunching.</li>
+<li>Occasionally, I write some lines of Java code for minor feature enhancements and fixes to improve the reliability of some the services.</li>
+<li>Sometimes, I still program in good old C. This is for special projects (e.g. I/O Riot) or low-level PoCs or SystemTap guru mode scripts.</li>
+</ul>
+<a class="textlink" href="./2021-05-16-personal-bash-coding-style-guide.html">Also have a look at my personal Bash coding style.</a><br />
+<a class="textlink" href="./2021-04-22-dtail-the-distributed-log-tail-program.html">Read here about DTail - the distributed log tail program.</a><br />
+<a class="textlink" href="./2018-06-01-realistic-load-testing-with-ioriot-for-linux.html">This is a magazine article about I/O Riot I wrote.</a><br />
+<p>For all other in-between tasks I mainly use the Ruby programming language (unless I decide to give something new a shot once in a while).</p>
+<h2>Being stuck in Ruby-mediocrity</h2>
+<p>As a Site Reliability Engineer there were many tasks and problems to be solved as efficiently and quickly as possible and, of course, without bugs. So I learned Ruby relatively fast by doing and the occasional web search for "how to do thing X". I always was eager to get the problem at hand done and as long as the code solved the problem I usually was happy.</p>
+<p>Until now, I never read a whole book or took a course on Ruby. As a result, I found myself writing Ruby in a Perl-ish procedural style (with Perl, you can do object-oriented programming too, but Perl wasn't designed from the ground up to be an object-oriented language). I didn't take advantage of all the specialities Ruby has to offer as I invested most of my time in the problems at hand and not in the Ruby idiomatic way of doing things.</p>
+<p>An unexpected benefit was that most of my Ruby code (probably not all, there are always dark corners in some old code bases lurking around) was easy to follow and extend or fix, even by people who usually don't speak Ruby, as there wasn't too much magic involved in my code - However, I could have done better still. Looking at other Ruby projects, I noticed over time that there is so much more to the language I wanted to explore. For example new techniques and the Ruby best practise, and much more about how things work under the hood, I wanted to learn about.</p>
+<h2>O'Reilly Safari Books Online</h2>
+<p>I do have an O'Reilly Safari Online subscription (thank you, employer). To my liking, I found the "The Well-Grounded Rubyist" book there (the text version and also the video version of it). I watched the video version for a couple of weeks, chunking the content into small pieces so it was able to fit into my schedule, increasing the playback speed for the topics I knew already well enough and slowed it down to actual pace when there was something new to learn and occasionally jumped back to the text book to review what I just learned. To my satisfaction, I was already familiar with over half of the language. But there was still the big chunk, especially how the magic happens under the hood in Ruby, which I missed out on, but I am happy now to be aware of it now.</p>
+<p>I also loved the occasional dry humour in the book: "An enumerator is like a brain in a science fiction movie, sitting on a table with no connection to a body but still able to think". :-)</p>
+<p>Will I rewrite and refactor all of my existing Ruby programs? Probably not, as they all do their work as intended. Some of these scripts will be eventually replaced or retired. But depending on the situation, I might refactor a module, class or a method or two once in a while. I already knew how to program in an object-oriented style from other languages (e.g. Java, C++, Perl Moose and plain) before I started Ruby, so my existing Ruby code is not as bad as you might assume after reading this article :-). In contrast to Java/C++, Ruby is a dynamic language, and the idiomatic ways of doing things differs from statically typed languages.</p>
+<h2>Key takeaways</h2>
+<p>These are the key takeaways. These only point out some specific things I have learned, and represent, by far, not everything I've learned from the book.</p>
+<h3>"Everything" is an object</h3>
+<p>In Ruby, everything is an object. However, Ruby is not Smalltalk. It depends on what you mean by "everything". Fixnums are objects. Classes also are, as instances of class Class. Methods, operators and blocks aren't but can be wrapped by objects via a "Proc". A simple assignment is not and can't. Statements like "while" also aren't and can't. Comments obviously also fall in the latter group. Ruby is more object-oriented than everything else I have ever seen, except for Smalltalk.</p>
+<p>In Ruby, like in Java/C++, classes are classes, objects are instances of classes, and there are class inheritances. There is single inheritance in Ruby, but with the power of mixing in modules, you can extend your classes in a better way than multiple class inheritances (like in C++) would allow. It's also different to Java interfaces, as interfaces in Java only come with the method prototypes and not with the actual method implementations like Ruby modules.</p>
+<h3>"Normal" objects and singleton objects</h3>
+<p>In Ruby, you can also have singleton objects. A singleton object can be an instance of a class but be modified after its creation (e.g. a method added to only this particular instance after its instantiation). Or, another variant of a singleton object is a class (yes, classes are also objects in Ruby). All of that is way better described in the Ruby book, so have a read by yourself if you are confused now; just remember: Rubys object system is very dynamic and flexible. At runtime, you can add and modify classes, objects of classes, singleton objects and modules. You don't need to restart the Ruby interpreter; you can change the code during runtime dynamically through Ruby code.</p>
+<h2>Domain specific languages</h2>
+<p>Due to Ruby's flexibility through object individualization (e.g. adding methods at runtime, or changing the core behaviour of classes, catching unknown method calls and dynamically dispatch and/or generate the missing methods via the "method_missing" method), Ruby is a very good language to write your own small domain specific language (DSL) on top of Ruby syntax. I only noticed that after reading this book. Maybe, this is one of the reasons why even the configuration management system Puppet once tried to use a Ruby DSL instead of the Puppet DSL for its manifests. I am not sure why the project got abandoned though, probably it has to do with performance. Do be honest, Ruby is not the fastest language, but it is fast enough for most use cases. And, especially from Ruby 3, performance is one of the main things being worked on currently. If I want performance, I can always use another programming language.</p>
+<h2>Ruby is "self-ish"</h2>
+<p>Ruby will fall back to the default "self" object if you don't specify an object method receiver. To give you an example, some more explanation is needed: There is the "Kernel" module mixed into almost every Ruby object. For example, "puts" is just a method of "Kernel". When you write "puts :foo", Ruby sends the message "puts" to the current object "self". The class of object "self" is "Object". Class Object has module "Kernel" mixed in, and "Kernel" defines the method "puts". </p>
+<pre>
+&gt;&gt; self
+=&gt; main
+&gt;&gt; self.class
+=&gt; Object
+&gt;&gt; self.class.included_modules
+=&gt; [PP::ObjectMixin, Kernel]
+&gt;&gt; Kernel.class
+=&gt; Module
+&gt;&gt; Kernel.methods.grep(/puts/)
+=&gt; [:puts]
+&gt;&gt; puts 'Hello Ruby'
+Hello Ruby
+=&gt; nil
+&gt;&gt; self.puts 'Hello World'
+Hello World
+=&gt; nil
+</pre>
+<p>Ruby offers a lot of syntactic sugar and seemingly magic, but it all comes back to objects and messages to objects under the hood. As all is hidden in objects, you can unwrap and even change the magic and see what's happening under the hood. Then, suddenly everything makes so much sense.</p>
+<h3>Functional programming</h3>
+<p>Ruby embraces an object-oriented programming style. But there is good news for fans of the functional programming paradigm: From immutable data (frozen objects), pure functions, lambdas and higher-order functions, lazy evaluation, tail-recursion optimization, method chaining, currying and partial function application, all of that is there. I am delighted about that, as I am a big fan of functional programming (having played with Haskell and Standard ML already).</p>
+<p>Remember, however, that Ruby is not a pure functional programming language. You, as a programmer, need to explicitly decide when to apply a functional style, as, by heart, Ruby is designed to be an object-oriented language. The language will not enforce side effect avoidance, and you will have to enable tail-recursion optimization (as of Ruby 2.5) explicitly, and variables/objects aren't immutable by default either. But that all does not hinder you from using these features. </p>
+<p>I liked this book so much so that I even bought myself a (used) paper copy of it. To my delight, there was also a free eBook version in ePub format included, which I now have on my Kobo Forma eBook reader. :-)</p>
+<h2>Perl</h2>
+<p>Will I abandon my beloved Perl? Probably not. There are also some Perl scripts I use at work. But unfortunately I only have a limited amount of time and I have to use it wisely. I might look into Raku (formerly known as Perl 6) next year and use it for a personal pet project, who knows. :-). I also highly recommend reading the two Perl books "Modern Perl" and "Higher-Order Perl".</p>
+<p>E-Mail me your thoughts at comments@mx.buetow.org!</p>
+<a class="textlink" href="../">Go back to the main site</a><br />
+</body>
+</html>
diff --git a/gemfeed/2021-07-04-the-well-grounded-rubyist/book-backside.jpg b/gemfeed/2021-07-04-the-well-grounded-rubyist/book-backside.jpg
new file mode 100644
index 00000000..2190e679
--- /dev/null
+++ b/gemfeed/2021-07-04-the-well-grounded-rubyist/book-backside.jpg
Binary files differ
diff --git a/gemfeed/2021-07-04-the-well-grounded-rubyist/book-cover.jpg b/gemfeed/2021-07-04-the-well-grounded-rubyist/book-cover.jpg
new file mode 100644
index 00000000..b5a00063
--- /dev/null
+++ b/gemfeed/2021-07-04-the-well-grounded-rubyist/book-cover.jpg
Binary files differ
diff --git a/gemfeed/atom.xml b/gemfeed/atom.xml
index 979d84fb..5aa23329 100644
--- a/gemfeed/atom.xml
+++ b/gemfeed/atom.xml
@@ -1,12 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
- <updated>2021-06-19T11:07:54+01:00</updated>
+ <updated>2021-07-04T14:28:40+01:00</updated>
<title>snonux.de feed</title>
<subtitle>Having fun with computers!</subtitle>
<link href="https://snonux.de/gemfeed/atom.xml" rel="self" />
<link href="https://snonux.de/" />
<id>https://snonux.de/</id>
<entry>
+ <title>The Well-Grounded Rubyist</title>
+ <link href="https://snonux.de/gemfeed/2021-07-04-the-well-grounded-rubyist.html" />
+ <id>https://snonux.de/gemfeed/2021-07-04-the-well-grounded-rubyist.html</id>
+ <updated>2021-07-04T10:51:23+01:00</updated>
+ <author>
+ <name>Paul Buetow</name>
+ <email>comments@mx.buetow.org</email>
+ </author>
+ <summary>When I was a Linux System Administrator, I have been programming in Perl for years. I still maintain some personal Perl programming projects (e.g. Xerl, guprecords, Loadbars). After switching jobs a couple of years ago (becoming a Site Reliability Engineer), I found Ruby (and some Python) widely used there. As I wanted to do something new, I then decided to give Ruby a go for all medium-sized programming and scripting projects.. .....to read on please visit my site.</summary>
+ <content type="xhtml">
+ <div xmlns="http://www.w3.org/1999/xhtml">
+ <h1>The Well-Grounded Rubyist</h1>
+<p class="quote"><i>Written by Paul Buetow 2021-07-04</i></p>
+<p>When I was a Linux System Administrator, I have been programming in Perl for years. I still maintain some personal Perl programming projects (e.g. Xerl, guprecords, Loadbars). After switching jobs a couple of years ago (becoming a Site Reliability Engineer), I found Ruby (and some Python) widely used there. As I wanted to do something new, I decided to give Ruby a go.</p>
+<p>You should learn or try out one new programming language once yearly anyway. If you end up not using the new language, that's not a problem. You will learn new techniques with each new programming language and this also helps you to improve your overall programming skills even for other languages. Also, having some background in a similar programming language makes it reasonably easy to get started. Besides that, learning a new programming language is kick-a** fun!</p>
+<a href="https://snonux.de/gemfeed/2021-07-04-the-well-grounded-rubyist/book-cover.jpg"><img src="https://snonux.de/gemfeed/2021-07-04-the-well-grounded-rubyist/book-cover.jpg" /></a><br />
+<p>Superficially, Perl seems to have many similarities to Ruby (but, of course, it is entirely different to Perl when you look closer), which pushed me towards Ruby instead of Python. I have tried Python a couple of times before, and I managed to write good code, but I never felt satisfied with the language. I didn't love the syntax, especially the indentations used; they always confused me. I don't dislike Python, but I don't prefer to program in it if I have a choice, especially when there are more propelling alternatives available. Personally, it's so much more fun to program in Ruby than in Python.</p>
+<a href="https://snonux.de/gemfeed/2021-07-04-the-well-grounded-rubyist/book-backside.jpg"><img src="https://snonux.de/gemfeed/2021-07-04-the-well-grounded-rubyist/book-backside.jpg" /></a><br />
+<p>Yukihiro Matsumoto, inventor of Ruby said: "I wanted a scripting language that was more powerful than Perl and more object-oriented than Python" - So I can see where some of the similarities come from. I personally don't believe that Ruby is more powerful than Perl, though, especially when you take CPAN and/or Perl 6 (now known as Raku) into the equation. Well, it all depends on what you mean with "more powerful". But I want to stay pragmatic and use what's already used at my workplace.</p>
+<h2>My Ruby problem domain</h2>
+<p>I wrote a lot of Ruby code over the last couple of years. There were many small to medium-sized tools and other projects such as Nagios monitoring checks, even an internal monitoring &amp; reporting site based on Sinatra. All Ruby scripts I wrote do their work well; I didn't encounter any significant problems using Ruby for any of these tasks. Of course, there's nothing that couldn't be written in Perl (or Python), though, after all, these languages are all Turing-complete and all these languages also come with a huge set of 3rd party libraries :-).</p>
+<p>I don't use Ruby for all programming projects, though. </p>
+<ul>
+<li>I am using Bash for small sized (usually below 500 lines of code) scripts and ad-hoc command-line automation.</li>
+<li>I program in Google Go for more complex tools (such as DTail) and for problem solving involving data crunching.</li>
+<li>Occasionally, I write some lines of Java code for minor feature enhancements and fixes to improve the reliability of some the services.</li>
+<li>Sometimes, I still program in good old C. This is for special projects (e.g. I/O Riot) or low-level PoCs or SystemTap guru mode scripts.</li>
+</ul>
+<a class="textlink" href="https://snonux.de/gemfeed/2021-05-16-personal-bash-coding-style-guide.html">Also have a look at my personal Bash coding style.</a><br />
+<a class="textlink" href="https://snonux.de/gemfeed/2021-04-22-dtail-the-distributed-log-tail-program.html">Read here about DTail - the distributed log tail program.</a><br />
+<a class="textlink" href="https://snonux.de/gemfeed/2018-06-01-realistic-load-testing-with-ioriot-for-linux.html">This is a magazine article about I/O Riot I wrote.</a><br />
+<p>For all other in-between tasks I mainly use the Ruby programming language (unless I decide to give something new a shot once in a while).</p>
+<h2>Being stuck in Ruby-mediocrity</h2>
+<p>As a Site Reliability Engineer there were many tasks and problems to be solved as efficiently and quickly as possible and, of course, without bugs. So I learned Ruby relatively fast by doing and the occasional web search for "how to do thing X". I always was eager to get the problem at hand done and as long as the code solved the problem I usually was happy.</p>
+<p>Until now, I never read a whole book or took a course on Ruby. As a result, I found myself writing Ruby in a Perl-ish procedural style (with Perl, you can do object-oriented programming too, but Perl wasn't designed from the ground up to be an object-oriented language). I didn't take advantage of all the specialities Ruby has to offer as I invested most of my time in the problems at hand and not in the Ruby idiomatic way of doing things.</p>
+<p>An unexpected benefit was that most of my Ruby code (probably not all, there are always dark corners in some old code bases lurking around) was easy to follow and extend or fix, even by people who usually don't speak Ruby, as there wasn't too much magic involved in my code - However, I could have done better still. Looking at other Ruby projects, I noticed over time that there is so much more to the language I wanted to explore. For example new techniques and the Ruby best practise, and much more about how things work under the hood, I wanted to learn about.</p>
+<h2>O'Reilly Safari Books Online</h2>
+<p>I do have an O'Reilly Safari Online subscription (thank you, employer). To my liking, I found the "The Well-Grounded Rubyist" book there (the text version and also the video version of it). I watched the video version for a couple of weeks, chunking the content into small pieces so it was able to fit into my schedule, increasing the playback speed for the topics I knew already well enough and slowed it down to actual pace when there was something new to learn and occasionally jumped back to the text book to review what I just learned. To my satisfaction, I was already familiar with over half of the language. But there was still the big chunk, especially how the magic happens under the hood in Ruby, which I missed out on, but I am happy now to be aware of it now.</p>
+<p>I also loved the occasional dry humour in the book: "An enumerator is like a brain in a science fiction movie, sitting on a table with no connection to a body but still able to think". :-)</p>
+<p>Will I rewrite and refactor all of my existing Ruby programs? Probably not, as they all do their work as intended. Some of these scripts will be eventually replaced or retired. But depending on the situation, I might refactor a module, class or a method or two once in a while. I already knew how to program in an object-oriented style from other languages (e.g. Java, C++, Perl Moose and plain) before I started Ruby, so my existing Ruby code is not as bad as you might assume after reading this article :-). In contrast to Java/C++, Ruby is a dynamic language, and the idiomatic ways of doing things differs from statically typed languages.</p>
+<h2>Key takeaways</h2>
+<p>These are the key takeaways. These only point out some specific things I have learned, and represent, by far, not everything I've learned from the book.</p>
+<h3>"Everything" is an object</h3>
+<p>In Ruby, everything is an object. However, Ruby is not Smalltalk. It depends on what you mean by "everything". Fixnums are objects. Classes also are, as instances of class Class. Methods, operators and blocks aren't but can be wrapped by objects via a "Proc". A simple assignment is not and can't. Statements like "while" also aren't and can't. Comments obviously also fall in the latter group. Ruby is more object-oriented than everything else I have ever seen, except for Smalltalk.</p>
+<p>In Ruby, like in Java/C++, classes are classes, objects are instances of classes, and there are class inheritances. There is single inheritance in Ruby, but with the power of mixing in modules, you can extend your classes in a better way than multiple class inheritances (like in C++) would allow. It's also different to Java interfaces, as interfaces in Java only come with the method prototypes and not with the actual method implementations like Ruby modules.</p>
+<h3>"Normal" objects and singleton objects</h3>
+<p>In Ruby, you can also have singleton objects. A singleton object can be an instance of a class but be modified after its creation (e.g. a method added to only this particular instance after its instantiation). Or, another variant of a singleton object is a class (yes, classes are also objects in Ruby). All of that is way better described in the Ruby book, so have a read by yourself if you are confused now; just remember: Rubys object system is very dynamic and flexible. At runtime, you can add and modify classes, objects of classes, singleton objects and modules. You don't need to restart the Ruby interpreter; you can change the code during runtime dynamically through Ruby code.</p>
+<h2>Domain specific languages</h2>
+<p>Due to Ruby's flexibility through object individualization (e.g. adding methods at runtime, or changing the core behaviour of classes, catching unknown method calls and dynamically dispatch and/or generate the missing methods via the "method_missing" method), Ruby is a very good language to write your own small domain specific language (DSL) on top of Ruby syntax. I only noticed that after reading this book. Maybe, this is one of the reasons why even the configuration management system Puppet once tried to use a Ruby DSL instead of the Puppet DSL for its manifests. I am not sure why the project got abandoned though, probably it has to do with performance. Do be honest, Ruby is not the fastest language, but it is fast enough for most use cases. And, especially from Ruby 3, performance is one of the main things being worked on currently. If I want performance, I can always use another programming language.</p>
+<h2>Ruby is "self-ish"</h2>
+<p>Ruby will fall back to the default "self" object if you don't specify an object method receiver. To give you an example, some more explanation is needed: There is the "Kernel" module mixed into almost every Ruby object. For example, "puts" is just a method of "Kernel". When you write "puts :foo", Ruby sends the message "puts" to the current object "self". The class of object "self" is "Object". Class Object has module "Kernel" mixed in, and "Kernel" defines the method "puts". </p>
+<pre>
+&gt;&gt; self
+=&gt; main
+&gt;&gt; self.class
+=&gt; Object
+&gt;&gt; self.class.included_modules
+=&gt; [PP::ObjectMixin, Kernel]
+&gt;&gt; Kernel.class
+=&gt; Module
+&gt;&gt; Kernel.methods.grep(/puts/)
+=&gt; [:puts]
+&gt;&gt; puts 'Hello Ruby'
+Hello Ruby
+=&gt; nil
+&gt;&gt; self.puts 'Hello World'
+Hello World
+=&gt; nil
+</pre>
+<p>Ruby offers a lot of syntactic sugar and seemingly magic, but it all comes back to objects and messages to objects under the hood. As all is hidden in objects, you can unwrap and even change the magic and see what's happening under the hood. Then, suddenly everything makes so much sense.</p>
+<h3>Functional programming</h3>
+<p>Ruby embraces an object-oriented programming style. But there is good news for fans of the functional programming paradigm: From immutable data (frozen objects), pure functions, lambdas and higher-order functions, lazy evaluation, tail-recursion optimization, method chaining, currying and partial function application, all of that is there. I am delighted about that, as I am a big fan of functional programming (having played with Haskell and Standard ML already).</p>
+<p>Remember, however, that Ruby is not a pure functional programming language. You, as a programmer, need to explicitly decide when to apply a functional style, as, by heart, Ruby is designed to be an object-oriented language. The language will not enforce side effect avoidance, and you will have to enable tail-recursion optimization (as of Ruby 2.5) explicitly, and variables/objects aren't immutable by default either. But that all does not hinder you from using these features. </p>
+<p>I liked this book so much so that I even bought myself a (used) paper copy of it. To my delight, there was also a free eBook version in ePub format included, which I now have on my Kobo Forma eBook reader. :-)</p>
+<h2>Perl</h2>
+<p>Will I abandon my beloved Perl? Probably not. There are also some Perl scripts I use at work. But unfortunately I only have a limited amount of time and I have to use it wisely. I might look into Raku (formerly known as Perl 6) next year and use it for a personal pet project, who knows. :-). I also highly recommend reading the two Perl books "Modern Perl" and "Higher-Order Perl".</p>
+<p>E-Mail me your thoughts at comments@mx.buetow.org!</p>
+ </div>
+ </content>
+ </entry>
+ <entry>
<title>Gemtexter - One Bash script to rule it all</title>
<link href="https://snonux.de/gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.html" />
<id>https://snonux.de/gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.html</id>
diff --git a/gemfeed/index.html b/gemfeed/index.html
index 3be23ea0..4e59598b 100644
--- a/gemfeed/index.html
+++ b/gemfeed/index.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
@@ -64,6 +64,7 @@ p.quote:after {
<body>
<h1>snonux.de's Gemfeed</h1>
<h2>Having fun with computers!</h2>
+<a class="textlink" href="./2021-07-04-the-well-grounded-rubyist.html">2021-07-04 (2048 words) - The Well-Grounded Rubyist</a><br />
<a class="textlink" href="./2021-06-05-gemtexter-one-bash-script-to-rule-it-all.html">2021-06-05 (1191 words) - Gemtexter - One Bash script to rule it all</a><br />
<a class="textlink" href="./2021-05-16-personal-bash-coding-style-guide.html">2021-05-16 (1717 words) - Personal Bash coding style guide</a><br />
<a class="textlink" href="./2021-04-24-welcome-to-the-geminispace.html">2021-04-24 (0797 words) - Welcome to the Geminispace</a><br />
diff --git a/index.html b/index.html
index aece1a13..c65b1bce 100644
--- a/index.html
+++ b/index.html
@@ -37,7 +37,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -48,7 +48,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
@@ -101,6 +101,7 @@ p.quote:after {
<a class="textlink" href="./gemfeed/index.html">Subscribe to this blog's Gemfeed</a><br />
<h3>Posts</h3>
<p>I have switched blog software multiple times. I might be backfilling some of the older articles here. So please don't wonder when suddenly old posts appear here.</p>
+<a class="textlink" href="./gemfeed/2021-07-04-the-well-grounded-rubyist.html">2021-07-04 (2048 words) - The Well-Grounded Rubyist</a><br />
<a class="textlink" href="./gemfeed/2021-06-05-gemtexter-one-bash-script-to-rule-it-all.html">2021-06-05 (1191 words) - Gemtexter - One Bash script to rule it all</a><br />
<a class="textlink" href="./gemfeed/2021-05-16-personal-bash-coding-style-guide.html">2021-05-16 (1717 words) - Personal Bash coding style guide</a><br />
<a class="textlink" href="./gemfeed/2021-04-24-welcome-to-the-geminispace.html">2021-04-24 (0797 words) - Welcome to the Geminispace</a><br />
diff --git a/resources.html b/resources.html
index 743ab111..1b1d2251 100644
--- a/resources.html
+++ b/resources.html
@@ -36,7 +36,7 @@ img {
pre {
display: block;
background-color: #111;
- color: #0ca;
+ color: #66cdaa;
padding: 5px;
overflow-x: auto;
}
@@ -47,7 +47,7 @@ a.textlink:before {
}
p.quote {
- color: #82EEFD;
+ color: #82eefd;
}
p.quote:before {
@@ -78,33 +78,34 @@ p.quote:after {
</pre>
<h2>Technical books</h2>
<ul>
-<li>Site Reliability Engineering; How Google runs production systems; O'Reilly</li>
-<li>Concurrency in Go; Katherine Cox-Buday; O'Reilly</li>
-<li>Learn You Some Erlang for Great Good; Fred Herbert; No Starch Press</li>
-<li>21st Century C: C Tips from the New School; Ben Klemens; O'Reilly</li>
<li>Advanced Bash-Scripting Guide; Not an actual book, but could be</li>
-<li>Learn You a Haskell for Great Good!; Miran Lipovaca; No Starch Press</li>
-<li>Java ist auch eine Insel; Christian Ullenboom; </li>
<li>Data Science at the Command Line; Jeroen Janssens; O'Reilly</li>
-<li>The Practise of System and Network Administration; Thomas A. Limoncelli, Christina J. Hogan, Strata R. Chalup; Addison-Wesley Professional</li>
-<li>Clusterbau mit Linux-HA; Michael Schwartzkopff; O'Reilly</li>
-<li>Funktionale Programmierung; Peter Pepper; Springer</li>
+<li>Higher Order Perl; Mark Dominus; Morgan Kaufmann</li>
+<li>Effective awk programming; Arnold Robbins; O'Reilly</li>
<li>Systemprogrammierung in Go; Frank Müller; dpunkt</li>
<li>Programming Perl aka "The Camel Book"; Tom Christiansen, brian d foy, Larry Wall &amp; Jon Orwant; O'Reilly</li>
-<li>Pro Git; Scott Chacon, Ben Straub; Apress</li>
-<li>DNS and BIND; Cricket Liu; O'Reilly</li>
-<li>Effective awk programming; Arnold Robbins; O'Reilly</li>
-<li>The Docker Book; James Turnbull; Kindle</li>
-<li>C++ Programming Language; Bjarne Stroustrup;</li>
-<li>Distributed Systems: Principles and Paradigms; Andrew S. Tanenbaum; Pearson</li>
+<li>Think Raku (aka Think Perl 6); Laurent Rosenfeld, Allen B. Downey; O'Reilly</li>
+<li>Java ist auch eine Insel; Christian Ullenboom; </li>
+<li>Developing Games in Java; David Brackeen and others...; New Riders</li>
+<li>21st Century C: C Tips from the New School; Ben Klemens; O'Reilly</li>
+<li>The Go Programming Language; Alan A. A. Donovan; Addison-Wesley Professional</li>
+<li>Learn You a Haskell for Great Good!; Miran Lipovaca; No Starch Press</li>
<li>Pro Puppet; James Turnbull, Jeffrey McCune; Apress</li>
+<li>Concurrency in Go; Katherine Cox-Buday; O'Reilly</li>
+<li>The Practise of System and Network Administration; Thomas A. Limoncelli, Christina J. Hogan, Strata R. Chalup; Addison-Wesley Professional</li>
<li>Object-Oriented Programming with ANSI-C; Axel-Tobias Schreiner</li>
<li>Modern Perl; Chromatic ; Onyx Neon Press</li>
-<li>Developing Games in Java; David Brackeen and others...; New Riders</li>
-<li>Higher Order Perl; Mark Dominus; Morgan Kaufmann</li>
+<li>Learn You Some Erlang for Great Good; Fred Herbert; No Starch Press</li>
+<li>C++ Programming Language; Bjarne Stroustrup;</li>
+<li>The Docker Book; James Turnbull; Kindle</li>
+<li>The Pragmatic Programmer; David Thomas; Addison-Wesley</li>
+<li>Site Reliability Engineering; How Google runs production systems; O'Reilly</li>
+<li>DNS and BIND; Cricket Liu; O'Reilly</li>
+<li>Distributed Systems: Principles and Paradigms; Andrew S. Tanenbaum; Pearson</li>
<li>Systems Performance Tuning; Gian-Paolo D. Musumeci and others...; O'Reilly</li>
-<li>Think Raku (aka Think Perl 6); Laurent Rosenfeld, Allen B. Downey; O'Reilly</li>
-<li>The Go Programming Language; Alan A. A. Donovan; Addison-Wesley Professional</li>
+<li>Pro Git; Scott Chacon, Ben Straub; Apress</li>
+<li>Funktionale Programmierung; Peter Pepper; Springer</li>
+<li>Clusterbau mit Linux-HA; Michael Schwartzkopff; O'Reilly</li>
</ul>
<h2>Technical bibles</h2>
<p>I didn't read them from the beginning to the end, but I am using them to look up things.</p>
@@ -139,18 +140,20 @@ p.quote:after {
<p>Some of these were in-person with exams; others were online learning lectures only.</p>
<ul>
<li>Linux Security and Isolation APIs Training; Michael Kerrisk; 3-day on-site training</li>
-<li>MySQL Deep Dive Workshop; 2-day on-site training</li>
-<li>Protocol buffers; O'Reilly Online</li>
+<li>F5 Loadbalancers Training; 2-day on-site training; F5, Inc. </li>
<li>Algorithms Video Lectures; Robert Sedgewick; O'Reilly Online</li>
+<li>Ultimate Go Programming; Bill Kennedy; O'Reilly Online</li>
<li>Red Hat Certified System Administrator; Course + certification (Although I had the option, I decided not to take the next course as it is more effective to self learn what I need)</li>
+<li>Apache Tomcat Best Practises; 3-day on-site training</li>
+<li>The Well-Grounded Rubyist Video Edition; David. A. Black; O'Reilly Online</li>
+<li>Protocol buffers; O'Reilly Online</li>
+<li>MySQL Deep Dive Workshop; 2-day on-site training</li>
<li>Scripting Vim; Damian Conway; O'Reilly Online</li>
-<li>The Ultimate Kubernetes Bootcamp; School of Devops; O'Reilly Online</li>
-<li>Ultimate Go Programming; Bill Kennedy; O'Reilly Online</li>
<li>Structure and Interpretation of Computer Programs; Harold Abelson and more...; </li>
-<li>F5 Loadbalancers Training; 2-day on-site training; F5, Inc. </li>
-<li>Apache Tomcat Best Practises; 3-day on-site training</li>
+<li>The Ultimate Kubernetes Bootcamp; School of Devops; O'Reilly Online</li>
<li>Functional programming lecture; Remote University of Hagen</li>
</ul>
+<a class="textlink" href="./gemfeed/2021-07-04-the-well-grounded-rubyist.html">Read here about my thoughts on "The Well-Grounded Rubyist"</a><br />
<h2>Fiction and more books</h2>
<p>Many fiction and non-fiction books I read are not listed here. This site primarily includes resources that impacted me regarding my work and not on my personal life. Do you recommend a good Science Fiction Novel? E-Mail me; I can also provide my recommendations! :-)</p>
<h2>Formal education</h2>