-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Add blog posts section #46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,7 @@ | ||||||
| # Blog Posts | ||||||
|
|
||||||
| * 2025-04-21: [Enforcing Conventional Commits with GitHub Actions](blog_posts/2025-04-20-enforcing-conventional-commits-github.md) | ||||||
| * 2025-04-18: [Enforcing Conventional Commits with Git Hooks](blog_posts/2025-04-18-enforcing-conventional-commits-git.md) | ||||||
| * 2025-04-16: [Continuous Delivery for Ruby gems](blog_posts/2025-04-16-continuous-delivery-for-ruby-gems.md) | ||||||
| * 2024-03-11: [Testing Ruby code that calls `abort` and `exit`](blog_posts/2024-03-11-testing-ruby-exit-abort.adoc) | ||||||
|
||||||
| * 2024-03-11: [Testing Ruby code that calls `abort` and `exit`](blog_posts/2024-03-11-testing-ruby-exit-abort.adoc) | |
| * 2024-03-11: [Testing Ruby code that calls `abort` and `exit`](blog_posts/2024-03-11-testing-ruby-exit-abort.md) |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,134 @@ | ||||||
| # Defining Class Variables and Constants in an Anonymous Class | ||||||
|
|
||||||
| ## Class Variables | ||||||
|
|
||||||
| If you were creating a class using the `class` keyword, you could simply | ||||||
| do the following to create a class variable for the class: | ||||||
|
|
||||||
| ```Ruby | ||||||
| class MyClass | ||||||
| @@class_var = :foo | ||||||
|
Comment on lines
+8
to
+10
|
||||||
| end | ||||||
| ``` | ||||||
|
|
||||||
| However, when creating an anonymous class using `Class.new`, the following | ||||||
| will define the class variable on `Object` instead of on the new anonymous | ||||||
| class (this actually fails on Ruby 3.0.0 or later with a RuntimeError "class | ||||||
| variable access from toplevel": | ||||||
|
|
||||||
| ```Ruby | ||||||
| MyClass = Class.new do | ||||||
| @@class_var = :foo | ||||||
| end | ||||||
| ``` | ||||||
|
|
||||||
| This is because class variable references are lexically scoped. In the case | ||||||
| of anonymous classes, `Class.new` evaluates the given block with `class_eval` | ||||||
| which DOES NOT change the lexical scope for the block. This means that the lexical | ||||||
| scope inside the block is the same as the lexical scope outside the block. | ||||||
|
|
||||||
| To get the class variable to be defined on `MyClass` instead of `Object`, you | ||||||
| need to use the `class_variable_set` method: | ||||||
|
|
||||||
| ```Ruby | ||||||
| MyClass = Class.new do | ||||||
| self.class_variable_set(:@@class_var, :foo) | ||||||
| end | ||||||
| ``` | ||||||
|
|
||||||
| Using `self` in the method invokation `self.class_variable_set` is redundant. | ||||||
|
||||||
| Using `self` in the method invokation `self.class_variable_set` is redundant. | |
| Using `self` in the method invocation `self.class_variable_set` is redundant. |
Copilot
AI
Mar 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: “classs” should be “class”.
| the anonymous classs is to explicitly call `class_variable_set` in the anonymous | |
| the anonymous class is to explicitly call `class_variable_set` in the anonymous |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,256 @@ | ||||||
| # Testing Ruby code that calls `abort` and `exit` | ||||||
| James Couball | ||||||
| :toc: | ||||||
|
|
||||||
| Testing code that uses the `abort` or `exit` is a challenge for many developers. | ||||||
|
Comment on lines
+1
to
+5
|
||||||
| These methods are often used in command-line applications to terminate the program | ||||||
| early and return an exit status to the operating system. Developers often encounter | ||||||
| conflicting opinions and misleading advice when seeking clear guidance on this topic. | ||||||
|
|
||||||
| This article demystifies the testing of such code, offering a simple and | ||||||
| comprehensive approach for testing with both Minitest and RSpec. | ||||||
|
|
||||||
| ## How `Kernel#exit` and `Kernel#abort` work | ||||||
|
|
||||||
| To effectively test code that calls `exit` and `abort`, it is important to first | ||||||
| understand how these methods work. | ||||||
|
|
||||||
| Both `exit` and `abort` raise a `SystemExit` exception. Here is a simplified version | ||||||
| of the `exit` and `abort` methods to illustrate what they do: | ||||||
|
|
||||||
| ```ruby | ||||||
| # @param status [Boolean, Integer] the exit status | ||||||
| # | ||||||
| # If given an integer value, it is used as the program's exit status. | ||||||
| # | ||||||
| # If given a Boolean value, the program's exit status is system dependent | ||||||
| # and is typically 0 for true and 1 for false. | ||||||
| # | ||||||
| def exit(status = true) | ||||||
| raise SystemExit.new(status, 'exit') | ||||||
| end | ||||||
| ``` | ||||||
|
|
||||||
| ```ruby | ||||||
| def abort(message = nil) | ||||||
| $stderr.puts(message.to_s) if message | ||||||
| raise SystemExit.new(false, message) | ||||||
| end | ||||||
| ``` | ||||||
|
|
||||||
| Like any other exception, if the `SystemExit` exception is propagated to the | ||||||
| top-level of the program, it causes the program to terminate. | ||||||
|
|
||||||
| What makes `SystemExit` different from other exceptions is that it gives some control | ||||||
| over how the program is terminated. If a `SystemExit` exception is not handled, | ||||||
| neither an error message nor a backtrace are output and the program exits with the | ||||||
| exit status given in the exception. | ||||||
|
|
||||||
| The `exit` method allows for a status code to be specified, which can indicate to the | ||||||
| operating system or calling process that the program ended successfully or encountered an | ||||||
| error. | ||||||
|
|
||||||
| `exit`, `exit(true)` are equivalent and indicate that the program was successful. The | ||||||
| program's exit status is set to a system-dependent value to indicate success. This | ||||||
| value is 0 on Windows and Linux-like systems. | ||||||
|
|
||||||
| `exit(false)` indicates that the program encountered an error. | ||||||
| The program's exit status is set to a system-dependent value to indicate failure. | ||||||
| This value is 1 on Windows and Linux-like systems. | ||||||
|
|
||||||
| `exit` can be called with an integer value to set the program's exit status directly. | ||||||
| Unless a specific value is needed, it is recommended to use `exit(true)` or `exit(false)`. | ||||||
|
|
||||||
| The `abort` method always indicates an error in the program. It allows for a | ||||||
| message to be given which is output to stderr BEFORE the exception is raised. This | ||||||
| means that message is output even if the `SystemExit` exception is handled. | ||||||
|
|
||||||
| After outputting the message, the `abort` method functions like `exit(false)`. The | ||||||
| only difference is the raised exception's `message` attrribute is set to the message | ||||||
|
||||||
| only difference is the raised exception's `message` attrribute is set to the message | |
| only difference is the raised exception's `message` attribute is set to the message |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The displayed date (2025-04-21) doesn’t match the linked post filename/date (
2025-04-20-enforcing-conventional-commits-github.md). Align the date and link target to keep the index chronological and accurate.