# Aaron Patterson

Published articles for Aaron Patterson.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Claims About RubyGems Caching and RubyDoc Code Execution

DevFeed: [Claims About RubyGems Caching and RubyDoc Code Execution](<https://devfeed.tech/articles/what-a-time-to-be-alive-39007.md>)

Original publisher: [Read original article](<https://tenderlovemaking.com/2026/09/11/what-a-time-to-be-alive/>)

Published: 2026-09-12T00:02:11Z

Content type: opinion

Language: en

Sources: [Aaron Patterson](<https://devfeed.tech/sources/aaron-patterson.md>)

Topics: [rubygems](<https://devfeed.tech/topics/rubygems.md>), [Caching](<https://devfeed.tech/topics/caching.md>), [vulnerability](<https://devfeed.tech/topics/vulnerability.md>), [Docker](<https://devfeed.tech/topics/docker.md>), [Web Scraping](<https://devfeed.tech/topics/web-scraping.md>)

Tags: [caching](<https://devfeed.tech/tags/caching.md>), [docker](<https://devfeed.tech/tags/docker.md>), [rubygems](<https://devfeed.tech/tags/rubygems.md>), [scraping](<https://devfeed.tech/tags/scraping.md>), [vulnerability](<https://devfeed.tech/tags/vulnerability.md>)

### AI overview

An opinion post discusses alleged RubyGems activity involving a caching vulnerability and web scraping. It also describes how published gems can cause RubyDoc.info to run YARD-loaded code in a networked Docker container.

### Source excerpt

Today Reuters and the Wall Street Journal both reported about rogue AI agents at OpenAI attacking RubyGems.org. https://www.rubyhack.ai/ has an amazing writeup, and you should read it. I just wanted to make a quick post about it because it's wild. TL;DR: It seems like OpenAI Bots knew about the RubyGems caching vulnerability, tried to take advantage of it, and at the same time ran some weird web scraping code on RubyDoc.info. Back in May, socket.dev reported about a "GemStuffer Campaign" where someone (I guess OpenAI) was uploading tons of junk gems to RubyGems.org. For some reason, the gems would scrape UK government websites, then repackage the data as gems, and attempt to upload them to RubyGems. I honestly didn't think much about this (or even look into it) until Sydney Von Arx and Spencer Kitts (both co-authors on https://www.rubyhack.ai) contacted me asking about RubyGems. I thought the claims they were making were completely outlandish until I actually read the code in these "GemStuffer" gems. After reading the code in these gems, a couple things stood out to me. YARD Documentation First, the gems leverage YARD documentation to execute arbitrary code on host machines. In most of the examples you'll see a .yardopts file that looks like this: --load ./script.rb README.md lib/**/*.rb Here's a link to an example. If you have YARD installed, and you install this gem, then YARD will load and run whatever is in ./script.rb from inside the gem. I think it's pretty common knowledge that C extensions will execute extconf.rb (so you basically have an RCE vector), but I was surprised to find out that a documentation tool would do that too. Nobody is going to install a gem named slnleaker5 though, so why would this matter? Well, any time a Gem is published RubyDoc.info will download the gem and process the YARD documentation. RubyDoc.info will execute the arbitrary code inside a Docker container. The Docker container still has network access though, so these gems could ha

## Detecting Full Table Scans With SQLite

DevFeed: [Detecting Full Table Scans With SQLite](<https://devfeed.tech/articles/detecting-full-table-scans-with-sqlite-39006.md>)

Original publisher: [Read original article](<https://tenderlovemaking.com/2026/07/15/detecting-full-table-scans-with-sqlite/>)

Published: 2026-07-15T15:26:22Z

Content type: tutorial

Language: en

Sources: [Aaron Patterson](<https://devfeed.tech/sources/aaron-patterson.md>)

Topics: [SQLite](<https://devfeed.tech/topics/sqlite.md>), [Databases](<https://devfeed.tech/topics/databases.md>), [Development](<https://devfeed.tech/topics/development.md>), [Rails](<https://devfeed.tech/topics/rails.md>)

Tags: [database](<https://devfeed.tech/tags/database.md>), [index](<https://devfeed.tech/tags/index.md>), [query](<https://devfeed.tech/tags/query.md>), [rails](<https://devfeed.tech/tags/rails.md>), [sqlite](<https://devfeed.tech/tags/sqlite.md>), [test](<https://devfeed.tech/tags/test.md>)

### AI overview

This tutorial shows how to detect full table scans in SQLite by inspecting prepared-statement statistics after executing a query. It demonstrates checking full-scan steps, then adding an index to eliminate the scan, and discusses possible Rails integration for test or development warnings.

### Source excerpt

I'm at RubyConf this week, and it's great! I recently read that lobste.rs is now running on SQLite. One part from the post caught my attention: I wish we could say in a test, "Fail if you encounter any full table scans". Which would have caught the perf issues we experienced during the first deploy. SQLite collects information about prepared statements and exposes those statistics though an API. The upshot of this is that we can tell whether a statement did a full table scan after executing the statement without using an EXPLAIN. Here's an example program that demonstrates detecting a query did a full table scan: db = SQLite3::Database.new(":memory:") db.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)") # Insert a bunch of records 1_000.times do |i| db.execute("INSERT INTO users (name, age) VALUES (?, ?)", ["user#{i}", i % 100]) end def query(db) # Prepare a statement and query it stmt = db.prepare("SELECT * FROM users WHERE age = ?") stmt.bind_param(1, 42) stmt.to_a # Check the number of full scan steps to detect full table scan fullscan_steps = stmt.stat(:fullscan_steps) puts "fullscan_steps: #{fullscan_steps}" if fullscan_steps > 0 puts " => query performed a full table scan" else puts " => no full table scan" end end # No index, so we'll see a full table scan query(db) # Create an index db.execute("CREATE INDEX idx_users_age ON users(age)") # Added an index, so no full table scan query(db) Feels like we could integrate this in to Rails and warn or raise in test / development. I'm not sure if we'd want to check this all the time in production, but maybe it would be fine?

## Rails Security, AI, and IBB

DevFeed: [Rails Security, AI, and IBB](<https://devfeed.tech/articles/rails-security-ai-and-ibb-39005.md>)

Original publisher: [Read original article](<https://tenderlovemaking.com/2026/05/06/rails-security-ai-and-ibb/>)

Published: 2026-05-06T17:31:54Z

Content type: opinion

Language: en

Sources: [Aaron Patterson](<https://devfeed.tech/sources/aaron-patterson.md>)

Topics: [Rails](<https://devfeed.tech/topics/rails.md>), [Artificial Intelligence](<https://devfeed.tech/topics/ai.md>), [Bug Bounty](<https://devfeed.tech/topics/bugbounty.md>), [Security](<https://devfeed.tech/topics/security.md>)

Tags: [ai](<https://devfeed.tech/tags/ai.md>), [bug-bounty](<https://devfeed.tech/tags/bug-bounty.md>), [rails](<https://devfeed.tech/tags/rails.md>), [security](<https://devfeed.tech/tags/security.md>)

### AI overview

A Rails team member reflects on the Internet Bug Bounty program, describing how AI-generated low-quality security reports overwhelmed the team and contributed to the program stopping new submissions and bounty payments. The change also removed incentives for legitimate researchers and left Rails handling payment-related questions.

### Source excerpt

For quite a few years the Rails project has been working with the Internet Bug Bounty (IBB). The IBB is an organization that awarded cash to security researchers that reported issues to OSS projects participating in the IBB. For quite a while I wasn't certain about my feelings toward the program because I felt like cash rewards could incentivize low quality reports as well as encourage reporters to "haggle" about the severity of a particular bug (the IBB paid more when the bug was more severe). In the beginning that certainly was the case. We were fielding many low quality reports, and people were haggling over severity. But the program evolved, and despite the never-ending haggling, I felt it did more good (rewarding security researchers) than bad (forcing the security team to wade through low quality reports). That is, until AI came along. Sometime in 2025 our team started getting inundated with low quality AI generated reports. I know for sure this wasn't unique to just our team as well. Anyway, AI lowered the barrier to generate reports, so we were back in the era of wading through low quality reports. Only this time, the low quality reports were masquerading as high quality reports. AI made it easy to turn a bullshit problem into something that looked legit, and since there's a possibility of money involved people tried to take advantage of the situation. We even had a report where someone forgot to delete the AI generated output and just uploaded the report as-is with the following text: ## ✅ READY TO SUBMIT! *All information prepared for professional Rails bug bounty submission.* *Expected Outcome:* Rails Team Response: 1-2 weeks Fix Development: 2-8 weeks Security Release: 8-12 weeks IBB Bounty: $1,040-1,600 (80% of $1,300-2,000) *Next Step:* Copy information above into HackerOne form and submit! I enjoy using AI, but I really don't like AI being used on me. But that's not what this post is about. Recently the IBB stopped accepting new submissions. In other

## Pixoo64 Ruby Client

DevFeed: [Pixoo64 Ruby Client](<https://devfeed.tech/articles/pixoo64-ruby-client-39004.md>)

Original publisher: [Read original article](<https://tenderlovemaking.com/2026/01/01/pixoo64-ruby-client/>)

Published: 2026-01-02T03:17:26Z

Content type: article

Language: en

Sources: [Aaron Patterson](<https://devfeed.tech/sources/aaron-patterson.md>)

Topics: [Ruby](<https://devfeed.tech/topics/ruby.md>), [API](<https://devfeed.tech/topics/api.md>), [Code](<https://devfeed.tech/topics/code.md>), [HTTP](<https://devfeed.tech/topics/http.md>), [client](<https://devfeed.tech/topics/client.md>), [data](<https://devfeed.tech/topics/data.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [client](<https://devfeed.tech/tags/client.md>), [code](<https://devfeed.tech/tags/code.md>), [data](<https://devfeed.tech/tags/data.md>), [http](<https://devfeed.tech/tags/http.md>), [ruby](<https://devfeed.tech/tags/ruby.md>)

### AI overview

The author describes building a Ruby client for the Pixoo64 LED display. The client uses the display's HTTP API, converts PNG files to the sign's binary format, and supports a setup that fetches PM2.5 and CO2 data from a remote server.

### Source excerpt

I bought a Pixoo64 LED Display to play around with, and I love it! It connects to WiFi and has an on-board HTTP API so you can program it. I made a Ruby client for it that even includes code to convert PNG files to the binary format the sign wants. One cool thing is that the display can be configured to fetch data from a remote server, so I configured mine to fetch PM2.5 and CO2 data for my office. Here's what it's looking like so far: Yes, this is how I discovered I need to open a window 😂

## Can Bundler Be as Fast as uv?

DevFeed: [Can Bundler Be as Fast as uv?](<https://devfeed.tech/articles/can-bundler-be-as-fast-as-uv-39003.md>)

Original publisher: [Read original article](<https://tenderlovemaking.com/2025/12/29/can-bundler-be-as-fast-as-uv/>)

Published: 2025-12-29T20:26:00Z

Content type: opinion

Language: en

Sources: [Aaron Patterson](<https://devfeed.tech/sources/aaron-patterson.md>)

Topics: [Ruby](<https://devfeed.tech/topics/ruby.md>), [rubygems](<https://devfeed.tech/topics/rubygems.md>), [Rust](<https://devfeed.tech/topics/rust.md>)

Tags: [packaging](<https://devfeed.tech/tags/packaging.md>), [performance](<https://devfeed.tech/tags/performance.md>), [ruby](<https://devfeed.tech/tags/ruby.md>), [rubygems](<https://devfeed.tech/tags/rubygems.md>), [rust](<https://devfeed.tech/tags/rust.md>)

### AI overview

The article examines whether Bundler can approach uv's package-installation speed. It reviews performance techniques from uv, considers how they apply to Bundler and RubyGems, and discusses existing bottlenecks and possible improvements.

### Source excerpt

At RailsWorld earlier this year, I got nerd sniped by someone. They asked "why can't Bundler be as fast as uv?" Immediately my inner voice said "YA, WHY CAN'T IT BE AS FAST AS UV????" My inner voice likes to shout at me, especially when someone asks a question so obvious I should have thought of it myself. Since then I've been thinking about and investigating this problem, going so far as to give a presentation at XO Ruby Portland about Bundler performance. I firmly believe the answer is "Bundler can be as fast as uv" (where "as fast" has a margin of error lol). Fortunately, Andrew Nesbitt recently wrote a post called "How uv got so fast", and I thought I would take this opportunity to review some of the highlights of the post and how techniques applied in uv can (or can't) be applied to Bundler / RubyGems. I'd also like to discuss some of the existing bottlenecks in Bundler and what we can do to fix them. If you haven't read Andrew's post, I highly recommend giving it a read. I'm going to quote some parts of the post and try to reframe them with RubyGems / Bundler in mind. Rewrite in Rust? Andrew opens the post talking about rewriting in Rust: uv installs packages faster than pip by an order of magnitude. The usual explanation is "it's written in Rust." That's true, but it doesn't explain much. Plenty of tools are written in Rust without being notably fast. The interesting question is what design decisions made the difference. This is such a good quote. I'm going to address "rewrite in Rust" a bit later in the post. But suffice to say, I think if we eliminate bottlenecks in Bundler such that the only viable option for performance improvements is to "rewrite in Rust", then I'll call it a success. I think rewrites give developers the freedom to "think outside the box", and try techniques they might not have tried. In the case of uv, I think it gave the developers a good way to say "if we don't have to worry about backwards compatibility, what could we achieve?". I su

## Apple Photos App Corrupts Images

DevFeed: [Apple Photos App Corrupts Images](<https://devfeed.tech/articles/apple-photos-app-corrupts-images-39002.md>)

Original publisher: [Read original article](<https://tenderlovemaking.com/2025/09/17/apple-photos-app-corrupts-images/>)

Published: 2025-09-16T23:59:23Z

Content type: article

Language: en

Sources: [Aaron Patterson](<https://devfeed.tech/sources/aaron-patterson.md>)

Topics: [App](<https://devfeed.tech/topics/app.md>), [file](<https://devfeed.tech/topics/file.md>), [import](<https://devfeed.tech/topics/import.md>), [debug](<https://devfeed.tech/topics/debug.md>), [Image](<https://devfeed.tech/topics/image.md>), [Hardware](<https://devfeed.tech/topics/hardware.md>), [USB](<https://devfeed.tech/topics/usb.md>)

Tags: [app](<https://devfeed.tech/tags/app.md>), [camera](<https://devfeed.tech/tags/camera.md>), [debug](<https://devfeed.tech/tags/debug.md>), [file](<https://devfeed.tech/tags/file.md>), [files](<https://devfeed.tech/tags/files.md>), [hardware](<https://devfeed.tech/tags/hardware.md>), [images](<https://devfeed.tech/tags/images.md>), [import](<https://devfeed.tech/tags/import.md>), [photo](<https://devfeed.tech/tags/photo.md>), [photos](<https://devfeed.tech/tags/photos.md>), [trust](<https://devfeed.tech/tags/trust.md>), [usb](<https://devfeed.tech/tags/usb.md>)

### AI overview

The article describes intermittent image corruption in Apple Photos when importing photos from an OM System OM-1 camera. The author reports corrupted JPEG and RAW files, estimates losing about 30% of the images from one event, investigates possible hardware causes, and changes to a different import workflow after losing trust in Photos.

### Source excerpt

The Apple Photos app sometimes corrupts images when importing from my camera. I just wanted to make a blog post about it in case anyone else runs into the problem. I've seen other references to this online, but most of the people gave up trying to fix it, and none of them went as far as I did to debug the issue. I'll try to describe the problem, and the things I've tried to do to fix it. But also note that I've (sort of) given up on the Photos app too. Since I can't trust it to import photos from my camera, I switched to a different workflow. Here is a screenshot of a corrupted image in the Photos app: How I used to import images I've got an OM System OM-1 camera. I used to shoot in RAW + jpg, then when I would import to Photos app, I would check the "delete photos after import" checkbox in order to empty the SD card. Turns out "delete after import" was a huge mistake. Getting corrupted images I'm pretty sure I'd been getting corrupted images for a while, but it would only be 1 or 2 images out of thousands, so I thought nothing of it (it was probably my fault anyway, right?) But the problem really got me upset when last year I went to a family member's wedding and took tons of photos. Apple Photos combines RAW + jpg photos so you don't have a bunch of duplicates, and when you view the images in the photos app, it just shows you the jpg version by default. After I imported all of the wedding photos I noticed some of them were corrupted. Upon closer inspection, I found that it sometimes had corrupted the jpg, sometimes corrupted the RAW file, and sometimes both. Since I had been checking the "delete after import" box, I didn't know if the images on the SD card were corrupted before importing or not. After all, the files had been deleted so there was no way to check. I estimate I completely lost about 30% of the images I took that day. Losing so many photos really rattled me, but I wanted to figure out the problem so I didn't lose images in the future. Narrowing down t

## File preallocation on macOS in Ruby

DevFeed: [File preallocation on macOS in Ruby](<https://devfeed.tech/articles/file-preallocation-on-macos-in-ruby-39001.md>)

Original publisher: [Read original article](<https://tenderlovemaking.com/2025/09/10/file-preallocation-on-macos-in-ruby/>)

Published: 2025-09-09T22:12:21Z

Content type: tutorial

Language: en

Sources: [Aaron Patterson](<https://devfeed.tech/sources/aaron-patterson.md>)

Topics: [macOS](<https://devfeed.tech/topics/macos.md>), [Ruby](<https://devfeed.tech/topics/ruby.md>), [Filesystems](<https://devfeed.tech/topics/filesystems.md>), [Code](<https://devfeed.tech/topics/code.md>), [implementation](<https://devfeed.tech/topics/implementation.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [file](<https://devfeed.tech/tags/file.md>), [files](<https://devfeed.tech/tags/files.md>), [macos](<https://devfeed.tech/tags/macos.md>), [ruby](<https://devfeed.tech/tags/ruby.md>)

### AI overview

This article demonstrates how to preallocate a file on macOS using Ruby, the fcntl gem, and macOS file-control constants. The example creates a file named "foo" with a size of 1234 bytes. The author notes that the attempted performance optimization did not produce useful results.

### Source excerpt

I haven't blogged in a while, so I figured I should do that. Jet lag has blessed me with some free time this morning, so I figured I would make some content in order to feed the AI bots. I've been messing around with pre-allocating files on the file system on macOS. This is useful in cases where you have a large file you need to copy, and you want to copy it quickly. For example, a tar implementation where the tar file might contain large files you need to copy. Here is the code: require "fcntl" # typedef struct fstore { # u_int32_t fst_flags; /* IN: flags word */ # int fst_posmode; /* IN: indicates offset field */ # off_t fst_offset; /* IN: start of the region */ # off_t fst_length; /* IN: size of the region */ # off_t fst_bytesalloc; /* OUT: number of bytes allocated */ # } fstore_t; size = 1234 fmt = [Fcntl::F_ALLOCATECONTIG, Fcntl::F_PEOFPOSMODE, 0, size, 0] bytes = fmt.pack("LlQQQ") File.open("foo", "wb") { |fd| fd.fcntl(Fcntl::F_PREALLOCATE, bytes) fd.truncate size } If you run this script, you'll find a file named "foo" with the size 1234. For this code to work, you'll need to be on macOS, and using this branch of the fcntl gem (though hopefully my patch will make it upstream and you can just use the fcntl gem). I tried implementing this as a performance optimization, but unfortunately the performance optimization didn't work out, so I'm probably not going to use this code IRL. Rather than leaving the code to rot on my computer, I figured I'd make a blog post so at least people can search for it, or I can train the LLMs in my image (lol). Anyway, thanks for reading my very niche content! Have a good day!

## Monkey Patch Detection in Ruby

DevFeed: [Monkey Patch Detection in Ruby](<https://devfeed.tech/articles/monkey-patch-detection-in-ruby-39000.md>)

Original publisher: [Read original article](<https://tenderlovemaking.com/2024/10/16/monkey-patch-detection-in-ruby/>)

Published: 2024-10-16T23:13:00Z

Content type: tutorial

Language: en

Sources: [Aaron Patterson](<https://devfeed.tech/sources/aaron-patterson.md>)

Topics: [Ruby](<https://devfeed.tech/topics/ruby.md>), [Optimization](<https://devfeed.tech/topics/optimization.md>), [implementation](<https://devfeed.tech/topics/implementation.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [code](<https://devfeed.tech/tags/code.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [monkey-patching](<https://devfeed.tech/tags/monkey-patching.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [ruby](<https://devfeed.tech/tags/ruby.md>)

### AI overview

This article explains how CRuby detects monkey patches to methods involved in optimizations and de-optimizes when a relevant method is redefined. It describes method tables, redefinition checks, global flags, and class bitmap mappings.

### Source excerpt

My last post detailed one way that CRuby will eliminate some intermediate array allocations when using methods like Array#hash and Array#max. Part of the technique hinges on detecting when someone monkey patches array. Today, I thought we'd dive a little bit in to how CRuby detects and de-optimizes itself when these "important" methods get monkey patched. Monkey Patching Problem The optimization in the previous post made the assumption that the implementation Array#max was the original definition (as defined in Ruby itself). But the Ruby language allows us to reopen classes, redefine any methods we want, and that those methods will "just work". For example, if someone were to reopen Array and define a new max method, we would need to respect that monkey patch: class Array def max "hello!" end end puts [1, 2].max # => "hello!" In fact, a monkey patch implementation could mutate the array itself, so we're definitely required to allocate an array in the case that someone added their own max method: class Array def max self << :neat self end end x = [1, 2].max p x # => [1, 2, :neat] So how does CRuby detect that a method has been monkey patched? Method Definition Time Every time a method is defined, an entry is stored in a hash table pointed to by the current class. We call this the "method table", but you'll see it referred to as M_TBL or RCLASS_M_TBL in the code. The key to the hash is simply the method name as an ID type (an integer which represents a Ruby Symbol), and the value of the hash is a method entry structure. If there was already an entry in the table, then we know it's a "redefinition" (a.k.a. "monkey patch"), and we end up calling rb_vm_check_redefinition_opt_method here. rb_vm_check_redefinition_opt_method checks to see if this is a method we "care" about. Methods we "care" about are typically ones where we've made some kind of optimization and we need to deoptimize if someone redefines them. If the redefined method is something we care to detect, then w

## Eliminating Intermediate Array Allocations

DevFeed: [Eliminating Intermediate Array Allocations](<https://devfeed.tech/articles/eliminating-intermediate-array-allocations-38999.md>)

Original publisher: [Read original article](<https://tenderlovemaking.com/2024/09/29/eliminating-intermediate-array-allocations/>)

Published: 2024-09-30T02:06:28Z

Content type: tutorial

Language: en

Sources: [Aaron Patterson](<https://devfeed.tech/sources/aaron-patterson.md>)

Topics: [Ruby](<https://devfeed.tech/topics/ruby.md>), [Code](<https://devfeed.tech/topics/code.md>), [tagged pointers](<https://devfeed.tech/topics/tagged-pointers.md>), [math](<https://devfeed.tech/topics/math.md>)

Tags: [array](<https://devfeed.tech/tags/array.md>), [code](<https://devfeed.tech/tags/code.md>), [function](<https://devfeed.tech/tags/function.md>), [gc](<https://devfeed.tech/tags/gc.md>), [ruby](<https://devfeed.tech/tags/ruby.md>), [tagged-pointers](<https://devfeed.tech/tags/tagged-pointers.md>)

### AI overview

This Ruby article explains how to measure object allocations with GC.stat and distinguishes code that never, sometimes, or always allocates. It focuses on why an intermediate array used in certain min or max calculations can be allocated on the stack and discarded without requesting a new object from the garbage collector.

### Source excerpt

Recently I gave a talk at RailsWorld (hopefully they'll post the video soon), and part of my presentation was about eliminating allocations in tokenizers. I presented a simple function for measuring allocations: def allocations x = GC.stat(:total_allocated_objects) yield GC.stat(:total_allocated_objects) - x end Everything in Ruby is an object, but not all objects actually make allocations. We can use the above function to measure allocations made in a block. Here are some examples of code that never allocate: p allocations { true } # => 0 p allocations { false } # => 0 p allocations { nil } # => 0 p allocations { :hello } # => 0 p allocations { 1 } # => 0 p allocations { 2.3 } # => 0 p allocations { 0xFFFF_FFFF_FFFF_FFFF } # => 0 Literals like booleans, nil, symbols, integers, and floats are represented internally to CRuby as "tagged pointers" and they don't allocate anything when executed. Here is an example of code that sometimes allocates: # Depends on the size of the number p allocations { 1 + 2 } # => 0 p allocations { 0x3FFF_FFFF_FFFF_FFFF + 1 } # => 1 # Depends on `frozen_string_literal` p allocations { "hello!" } # => 0 or 1 Math on integers generally doesn't allocate anything, but it depends on the integer. When a number gets large enough, CRuby will allocate an object to represent that number. On 64 bit platforms, the largest whole number we can represent without allocating is 0x3FFF_FFFF_FFFF_FFFF. String literals will sometimes allocate, but it depends on the frozen_string_literal setting in your program. Here is an example of code that always allocates: p allocations { [1, 2] } # => 1 p allocations { { a: :b } } # => 1 p allocations { Object.new } # => 1 p allocations { "foo"[0, 1] } # => 1 Hopefully these examples are fairly straightforward. Arrays, hashes, objects, string slices, etc will allocate an object. Eliminating Intermediate Array Allocations At the Shopify after-party at RailsWorld, someone asked me a really great question. Their codebase ha

## Using Serial Ports with Ruby

DevFeed: [Using Serial Ports with Ruby](<https://devfeed.tech/articles/using-serial-ports-with-ruby-38998.md>)

Original publisher: [Read original article](<https://tenderlovemaking.com/2024/02/16/using-serial-ports-with-ruby/>)

Published: 2024-02-16T19:56:28Z

Content type: tutorial

Language: en

Sources: [Aaron Patterson](<https://devfeed.tech/sources/aaron-patterson.md>)

Topics: [Ruby](<https://devfeed.tech/topics/ruby.md>), [Embedded Systems](<https://devfeed.tech/topics/embedded-systems.md>), [Hardware](<https://devfeed.tech/topics/hardware.md>)

Tags: [embedded](<https://devfeed.tech/tags/embedded.md>), [embedded-systems](<https://devfeed.tech/tags/embedded-systems.md>), [firmware](<https://devfeed.tech/tags/firmware.md>), [hardware](<https://devfeed.tech/tags/hardware.md>), [ruby](<https://devfeed.tech/tags/ruby.md>), [streaming](<https://devfeed.tech/tags/streaming.md>)

### AI overview

A tutorial on using the UART gem with Ruby to communicate with a GMC-320 Geiger counter over a serial port. It demonstrates configuring the connection, retrieving the device firmware version, and preparing to process live updates with streaming data and timeouts.

### Source excerpt

Lets mess around with serial ports today! I love doing hardware hacking, and dealing with serial ports is a common thing you have to do when working with embedded systems. Of course I want to do everything with Ruby, and I had found Ruby serial port libraries to be either lacking, or too complex, so I decided to write my own. I feel like I've not done a good enough job promoting the library, so today we're going to mess with serial ports using the UART gem. Don't let the last commit date on the repo fool you, despite being over 6 years ago, this library is actively maintained (and I use it every day!). I've got a GMC-320 Geiger counter. Not only is the price pretty reasonable, but it also has a serial port interface! You can log data, then download the logged data via serial port. Today we're just going to write a very simple program that gets the firmware version via serial port, and then gets live updates from the device. This will allow us to start with UART basics in Ruby, and then work with streaming data and timeouts. The company that makes the Geiger counter published a spec for the UART commands that the device supports, so all we need to do is send the commands and read the results. According to the spec, the default UART config for my Geiger counter is 115200 BPS, Data bit: 8, no parity, Stop bit: 1, and no control. This is pretty easy to configure with the UART gem, all of these values are default except for the baud rate. The UART gem defaults to 9600 for the baud rate, so that's the only thing we'll have to configure. Getting the hardware version To get the hardware model and version, we just have to send <GETVER>> over the serial port and then read the response. Let's write a small program that will fetch the hardware model and version and print them out. require "uart" UART.open ARGV[0], 115200 do |serial| # Send the "get version" command serial.write "<GETVER>>" # read and print the result puts serial.read end The first thing we do is require the uar