diff options
| author | Paul Buetow <paul@buetow.org> | 2025-10-11 15:26:29 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-10-11 15:26:29 +0300 |
| commit | 73f50e3ee94cd892c1d0ac76599e73f4366fae6d (patch) | |
| tree | 57007003fb805fce7a38c1d57d3647f2b905b050 /gemfeed | |
| parent | e79ff3270912fc1ecac056339472af1f467d7434 (diff) | |
Update content for gemtext
Diffstat (limited to 'gemfeed')
| -rw-r--r-- | gemfeed/2021-07-04-the-well-grounded-rubyist.gmi | 5 | ||||
| -rw-r--r-- | gemfeed/2021-07-04-the-well-grounded-rubyist.gmi.tpl | 4 | ||||
| -rw-r--r-- | gemfeed/2025-10-11-the-well-grounded-rubyist-notes.gmi | 204 | ||||
| -rw-r--r-- | gemfeed/2025-10-11-the-well-grounded-rubyist-notes.gmi.tpl | 204 | ||||
| -rw-r--r-- | gemfeed/atom.xml | 387 | ||||
| -rw-r--r-- | gemfeed/index.gmi | 1 |
6 files changed, 663 insertions, 142 deletions
diff --git a/gemfeed/2021-07-04-the-well-grounded-rubyist.gmi b/gemfeed/2021-07-04-the-well-grounded-rubyist.gmi index 6f2952e8..29adf905 100644 --- a/gemfeed/2021-07-04-the-well-grounded-rubyist.gmi +++ b/gemfeed/2021-07-04-the-well-grounded-rubyist.gmi @@ -118,4 +118,9 @@ Will I abandon my beloved Perl? Probably not. There are also some Perl scripts I E-Mail your comments to `paul@nospam.buetow.org` :-) +Other Ruby-related posts: + +=> ./2025-10-11-the-well-grounded-rubyist-notes.gmi 2025-10-11 Key Takeaways from The Well-Grounded Rubyist +=> ./2021-07-04-the-well-grounded-rubyist.gmi 2021-07-04 The Well-Grounded Rubyist (You are currently reading this) + => ../ Back to the main site diff --git a/gemfeed/2021-07-04-the-well-grounded-rubyist.gmi.tpl b/gemfeed/2021-07-04-the-well-grounded-rubyist.gmi.tpl index 4434f170..19bb6109 100644 --- a/gemfeed/2021-07-04-the-well-grounded-rubyist.gmi.tpl +++ b/gemfeed/2021-07-04-the-well-grounded-rubyist.gmi.tpl @@ -106,4 +106,8 @@ Will I abandon my beloved Perl? Probably not. There are also some Perl scripts I E-Mail your comments to `paul@nospam.buetow.org` :-) +Other Ruby-related posts: + +<< template::inline::rindex ruby + => ../ Back to the main site diff --git a/gemfeed/2025-10-11-the-well-grounded-rubyist-notes.gmi b/gemfeed/2025-10-11-the-well-grounded-rubyist-notes.gmi new file mode 100644 index 00000000..7539433a --- /dev/null +++ b/gemfeed/2025-10-11-the-well-grounded-rubyist-notes.gmi @@ -0,0 +1,204 @@ +# Key Takeaways from The Well-Grounded Rubyist + +> Published at 2025-10-11T15:25:14+03:00 + +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'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. + +=> ./2021-07-04-the-well-grounded-rubyist.gmi My first post about the book. + +## The Object Model + +One of the most fascinating aspects of Ruby is its object model. The book does a great job of explaining the details. + +### Everything is an object (almost) + +In Ruby, most things are objects. This includes numbers, strings, and even classes themselves. This has some interesting consequences. For example, you can't use `i++` like in C or Java. Integers are immutable objects. `1` is always the same object. `1 + 1` returns a new object, `2`. + +### The `self` keyword + +There is always a current object, `self`. If you call a method without an explicit receiver, it's called on `self`. For example, `puts "hello"` is actually `self.puts "hello"`. + +```ruby +# At the top level, self is the main object +p self +# => main +p self.class +# => Object + +def foo + # Inside a method, self is the object that received the call + p self +end + +foo +# => main +``` + +This code demonstrates how `self` changes depending on the context. At the top level, it's `main`, an instance of `Object`. When `foo` is called without a receiver, it's called on `main`. + +### Singleton Methods + +You can add methods to individual objects. These are called singleton methods. + +```ruby +obj = "a string" + +def obj.shout + self.upcase + "!" +end + +p obj.shout +# => "A STRING!" + +obj2 = "another string" +# obj2.shout would raise a NoMethodError +``` + +Here, the `shout` method is only available on the `obj` object. This is a powerful feature for adding behavior to specific instances. + +### Classes are Objects + +Classes themselves are objects, instances of the `Class` class. This means you can create classes dynamically. + +```ruby +MyClass = Class.new do + def say_hello + puts "Hello from a dynamically created class!" + end +end + +instance = MyClass.new +instance.say_hello +# => Hello from a dynamically created class! +``` + +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 `class` keyword. + +## Control Flow and Methods + +The book clarified many things about how methods and control flow work in Ruby. + +### `case` and the `===` operator + +The `case` statement is more powerful than I thought. It uses the `===` (threequals or case equality) operator for comparison, not `==`. Different classes can implement `===` in their own way. + +```ruby +# For ranges, it checks for inclusion +p (1..5) === 3 # => true + +# For classes, it checks if the object is an instance of the class +p String === "hello" # => true + +# For regexes, it checks for a match +p /llo/ === "hello" # => true + +def check(value) + case value + when String + "It's a string" + when (1..10) + "It's a number between 1 and 10" + else + "Something else" + end +end + +p check(5) # => "It's a number between 1 and 10" +``` + +### Blocks and `yield` + +Blocks are a cornerstone of Ruby. You can pass them to methods to customize their behavior. The `yield` keyword is used to call the block. + +```ruby +def my_iterator + puts "Entering the method" + yield + puts "Back in the method" + yield +end + +my_iterator { puts "Inside the block" } +# Entering the method +# Inside the block +# Back in the method +# Inside the block +``` + +This simple iterator shows how `yield` transfers control to the block. You can also pass arguments to `yield` and get a return value from the block. + +```ruby +def with_return + result = yield(5) + puts "The block returned #{result}" +end + +with_return { |n| n * 2 } +# => The block returned 10 +``` + +This demonstrates passing an argument to the block and using its return value. + +## Fun with Data Types + +Ruby's core data types are full of nice little features. + +### Symbols + +Symbols are like immutable strings. They are great for keys in hashes because they are unique and memory-efficient. + +```ruby +# Two strings with the same content are different objects +p "foo".object_id +p "foo".object_id + +# Two symbols with the same content are the same object +p :foo.object_id +p :foo.object_id + +# Modern hash syntax uses symbols as keys +my_hash = { name: "Paul", language: "Ruby" } +p my_hash[:name] # => "Paul" +``` + +This code highlights the difference between strings and symbols and shows the convenient hash syntax. + +### Arrays and Hashes + +Arrays and hashes have a rich API. The `%w` and `%i` shortcuts for creating arrays of strings and symbols are very handy. + +```ruby +# Array of strings +p %w[one two three] +# => ["one", "two", "three"] + +# Array of symbols +p %i[one two three] +# => [:one, :two, :three] +``` + +A quick way to create arrays. You can also retrieve multiple values at once. + +```ruby +arr = [10, 20, 30, 40, 50] +p arr.values_at(0, 2, 4) +# => [10, 30, 50] + +hash = { a: 1, b: 2, c: 3 } +p hash.values_at(:a, :c) +# => [1, 3] +``` + +The `values_at` method is a concise way to get multiple elements. + +## Final Thoughts + +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't have time to process my notes there yet. + +E-Mail your comments to `paul@nospam.buetow.org` :-) + +Other Ruby-related posts: + +=> ./2021-07-04-the-well-grounded-rubyist.gmi 2021-07-04 The Well-Grounded Rubyist + +=> ../ Back to the main site diff --git a/gemfeed/2025-10-11-the-well-grounded-rubyist-notes.gmi.tpl b/gemfeed/2025-10-11-the-well-grounded-rubyist-notes.gmi.tpl new file mode 100644 index 00000000..eb56860e --- /dev/null +++ b/gemfeed/2025-10-11-the-well-grounded-rubyist-notes.gmi.tpl @@ -0,0 +1,204 @@ +# Key Takeaways from The Well-Grounded Rubyist + +> Published at 2025-10-11T15:25:14+03:00 + +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'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. + +=> ./2021-07-04-the-well-grounded-rubyist.gmi My first post about the book. + +## The Object Model + +One of the most fascinating aspects of Ruby is its object model. The book does a great job of explaining the details. + +### Everything is an object (almost) + +In Ruby, most things are objects. This includes numbers, strings, and even classes themselves. This has some interesting consequences. For example, you can't use `i++` like in C or Java. Integers are immutable objects. `1` is always the same object. `1 + 1` returns a new object, `2`. + +### The `self` keyword + +There is always a current object, `self`. If you call a method without an explicit receiver, it's called on `self`. For example, `puts "hello"` is actually `self.puts "hello"`. + +```ruby +# At the top level, self is the main object +p self +# => main +p self.class +# => Object + +def foo + # Inside a method, self is the object that received the call + p self +end + +foo +# => main +``` + +This code demonstrates how `self` changes depending on the context. At the top level, it's `main`, an instance of `Object`. When `foo` is called without a receiver, it's called on `main`. + +### Singleton Methods + +You can add methods to individual objects. These are called singleton methods. + +```ruby +obj = "a string" + +def obj.shout + self.upcase + "!" +end + +p obj.shout +# => "A STRING!" + +obj2 = "another string" +# obj2.shout would raise a NoMethodError +``` + +Here, the `shout` method is only available on the `obj` object. This is a powerful feature for adding behavior to specific instances. + +### Classes are Objects + +Classes themselves are objects, instances of the `Class` class. This means you can create classes dynamically. + +```ruby +MyClass = Class.new do + def say_hello + puts "Hello from a dynamically created class!" + end +end + +instance = MyClass.new +instance.say_hello +# => Hello from a dynamically created class! +``` + +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 `class` keyword. + +## Control Flow and Methods + +The book clarified many things about how methods and control flow work in Ruby. + +### `case` and the `===` operator + +The `case` statement is more powerful than I thought. It uses the `===` (threequals or case equality) operator for comparison, not `==`. Different classes can implement `===` in their own way. + +```ruby +# For ranges, it checks for inclusion +p (1..5) === 3 # => true + +# For classes, it checks if the object is an instance of the class +p String === "hello" # => true + +# For regexes, it checks for a match +p /llo/ === "hello" # => true + +def check(value) + case value + when String + "It's a string" + when (1..10) + "It's a number between 1 and 10" + else + "Something else" + end +end + +p check(5) # => "It's a number between 1 and 10" +``` + +### Blocks and `yield` + +Blocks are a cornerstone of Ruby. You can pass them to methods to customize their behavior. The `yield` keyword is used to call the block. + +```ruby +def my_iterator + puts "Entering the method" + yield + puts "Back in the method" + yield +end + +my_iterator { puts "Inside the block" } +# Entering the method +# Inside the block +# Back in the method +# Inside the block +``` + +This simple iterator shows how `yield` transfers control to the block. You can also pass arguments to `yield` and get a return value from the block. + +```ruby +def with_return + result = yield(5) + puts "The block returned #{result}" +end + +with_return { |n| n * 2 } +# => The block returned 10 +``` + +This demonstrates passing an argument to the block and using its return value. + +## Fun with Data Types + +Ruby's core data types are full of nice little features. + +### Symbols + +Symbols are like immutable strings. They are great for keys in hashes because they are unique and memory-efficient. + +```ruby +# Two strings with the same content are different objects +p "foo".object_id +p "foo".object_id + +# Two symbols with the same content are the same object +p :foo.object_id +p :foo.object_id + +# Modern hash syntax uses symbols as keys +my_hash = { name: "Paul", language: "Ruby" } +p my_hash[:name] # => "Paul" +``` + +This code highlights the difference between strings and symbols and shows the convenient hash syntax. + +### Arrays and Hashes + +Arrays and hashes have a rich API. The `%w` and `%i` shortcuts for creating arrays of strings and symbols are very handy. + +```ruby +# Array of strings +p %w[one two three] +# => ["one", "two", "three"] + +# Array of symbols +p %i[one two three] +# => [:one, :two, :three] +``` + +A quick way to create arrays. You can also retrieve multiple values at once. + +```ruby +arr = [10, 20, 30, 40, 50] +p arr.values_at(0, 2, 4) +# => [10, 30, 50] + +hash = { a: 1, b: 2, c: 3 } +p hash.values_at(:a, :c) +# => [1, 3] +``` + +The `values_at` method is a concise way to get multiple elements. + +## Final Thoughts + +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't have time to process my notes there yet. + +E-Mail your comments to `paul@nospam.buetow.org` :-) + +Other Ruby-related posts: + +<< template::inline::rindex ruby + +=> ../ Back to the main site diff --git a/gemfeed/atom.xml b/gemfeed/atom.xml index 68a3a2cc..264191d1 100644 --- a/gemfeed/atom.xml +++ b/gemfeed/atom.xml @@ -1,12 +1,256 @@ <?xml version="1.0" encoding="utf-8"?> <feed xmlns="http://www.w3.org/2005/Atom"> - <updated>2025-10-02T11:30:14+03:00</updated> + <updated>2025-10-11T15:25:15+03:00</updated> <title>foo.zone feed</title> <subtitle>To be in the .zone!</subtitle> <link href="gemini://foo.zone/gemfeed/atom.xml" rel="self" /> <link href="gemini://foo.zone/" /> <id>gemini://foo.zone/</id> <entry> + <title>Key Takeaways from The Well-Grounded Rubyist</title> + <link href="gemini://foo.zone/gemfeed/2025-10-11-the-well-grounded-rubyist-notes.gmi" /> + <id>gemini://foo.zone/gemfeed/2025-10-11-the-well-grounded-rubyist-notes.gmi</id> + <updated>2025-10-11T15:25:14+03:00</updated> + <author> + <name>Paul Buetow aka snonux</name> + <email>paul@dev.buetow.org</email> + </author> + <summary>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'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.</summary> + <content type="xhtml"> + <div xmlns="http://www.w3.org/1999/xhtml"> + <h1 style='display: inline' id='key-takeaways-from-the-well-grounded-rubyist'>Key Takeaways from The Well-Grounded Rubyist</h1><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'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 /> +<a class='textlink' href='./2021-07-04-the-well-grounded-rubyist.html'>My first post about the book.</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'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'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"># => 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"># => 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"># => 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'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'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"># => "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"># => 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"># => 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"># => 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"># => 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"># => "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"># => 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'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"># => "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"># => ["one", "two", "three"]</font></i> + +<i><font color="silver"># Array of symbols</font></i> +p %i[one two three] +<i><font color="silver"># => [: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"># => [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"># => [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'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='./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 /> + </div> + </content> + </entry> + <entry> <title>f3s: Kubernetes with FreeBSD - Part 7: k3s and first pod deployments</title> <link href="gemini://foo.zone/gemfeed/2025-10-02-f3s-kubernetes-with-freebsd-part-7.gmi" /> <id>gemini://foo.zone/gemfeed/2025-10-02-f3s-kubernetes-with-freebsd-part-7.gmi</id> @@ -14031,145 +14275,4 @@ DC on fire: </div> </content> </entry> - <entry> - <title>Gemtexter 2.1.0 - Let's Gemtext again³</title> - <link href="gemini://foo.zone/gemfeed/2023-07-21-gemtexter-2.1.0-lets-gemtext-again-3.gmi" /> - <id>gemini://foo.zone/gemfeed/2023-07-21-gemtexter-2.1.0-lets-gemtext-again-3.gmi</id> - <updated>2023-07-21T10:19:31+03:00</updated> - <author> - <name>Paul Buetow aka snonux</name> - <email>paul@dev.buetow.org</email> - </author> - <summary>I proudly announce that I've released Gemtexter version `2.1.0`. What is Gemtexter? It's my minimalist static site generator for Gemini Gemtext, HTML and Markdown, written in GNU Bash.</summary> - <content type="xhtml"> - <div xmlns="http://www.w3.org/1999/xhtml"> - <h1 style='display: inline' id='gemtexter-210---let-s-gemtext-again'>Gemtexter 2.1.0 - Let's Gemtext again³</h1><br /> -<br /> -<span class='quote'>Published at 2023-07-21T10:19:31+03:00</span><br /> -<br /> -<span>I proudly announce that I've released Gemtexter version <span class='inlinecode'>2.1.0</span>. What is Gemtexter? It's my minimalist static site generator for Gemini Gemtext, HTML and Markdown, written in GNU Bash.</span><br /> -<br /> -<a class='textlink' href='https://codeberg.org/snonux/gemtexter'>https://codeberg.org/snonux/gemtexter</a><br /> -<br /> -<pre> --=[ typewriters ]=- 1/98 - .-------. - .-------. _|~~ ~~ |_ - _|~~ ~~ |_ .-------. =(_|_______|_) - =(_|_______|_)= _|~~ ~~ |_ |:::::::::| - |:::::::::| =(_|_______|_) |:::::::[]| - |:::::::[]| |:::::::::| |o=======.| - |o=======.| |:::::::[]| `"""""""""` - jgs `"""""""""` |o=======.| - mod. by Paul Buetow `"""""""""` -</pre> -<br /> -<h2 style='display: inline' id='table-of-contents'>Table of Contents</h2><br /> -<br /> -<ul> -<li><a href='#gemtexter-210---let-s-gemtext-again'>Gemtexter 2.1.0 - Let's Gemtext again³</a></li> -<li>⇢ <a href='#why-bash'>Why Bash?</a></li> -<li>⇢ <a href='#switch-to-gpl3-license'>Switch to GPL3 license</a></li> -<li>⇢ <a href='#source-code-highlighting-support'>Source code highlighting support</a></li> -<li>⇢ <a href='#html-exact-variant'>HTML exact variant</a></li> -<li>⇢ <a href='#use-of-hack-webfont-by-default'>Use of Hack webfont by default</a></li> -<li>⇢ <a href='#html-mastodon-verification-support'>HTML Mastodon verification support</a></li> -<li>⇢ <a href='#more'>More</a></li> -</ul><br /> -<h2 style='display: inline' id='why-bash'>Why Bash?</h2><br /> -<br /> -<span>This project is too complex for a Bash script. Writing it in Bash was to try out how maintainable a "larger" Bash script could be. It's still pretty maintainable and helps me try new Bash tricks here and then!</span><br /> -<br /> -<span>Let's list what's new!</span><br /> -<br /> -<h2 style='display: inline' id='switch-to-gpl3-license'>Switch to GPL3 license</h2><br /> -<br /> -<span>Many (almost all) of the tools and commands (GNU Bash, GMU Sed, GNU Date, GNU Grep, GNU Source Highlight) used by <span class='inlinecode'>Gemtexter</span> are licensed under the GPL anyway. So why not use the same? This was an easy switch, as I was the only code contributor so far!</span><br /> -<br /> -<h2 style='display: inline' id='source-code-highlighting-support'>Source code highlighting support</h2><br /> -<br /> -<span>The HTML output now supports source code highlighting, which is pretty neat if your site is about programming. The requirement is to have the <span class='inlinecode'>source-highlight</span> command, which is GNU Source Highlight, to be installed. Once done, you can annotate a bare block with the language to be highlighted. E.g.:</span><br /> -<br /> -<pre> - ```bash - if [ -n "$foo" ]; then - echo "$foo" - fi - ``` -</pre> -<br /> -<span>The result will look like this (you can see the code highlighting only in the Web version, not in the Geminispace version of this site):</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">if</font></u></b> [ -n <font color="#808080">"$foo"</font> ]; <b><u><font color="#000000">then</font></u></b> - echo <font color="#808080">"$foo"</font> -<b><u><font color="#000000">fi</font></u></b> -</pre> -<br /> -<span>Please run <span class='inlinecode'>source-highlight --lang-list</span> for a list of all supported languages.</span><br /> -<br /> -<h2 style='display: inline' id='html-exact-variant'>HTML exact variant</h2><br /> -<br /> -<span>Gemtexter is there to convert |
