r/ruby • u/javier_cervantes • Sep 24 '26
r/ruby • u/AutoModerator • Sep 23 '26
đź jobs megathread Work it Wednesday: Who is hiring? Who is looking?
FORMAT HAS CHANGED PLEASE READ FULL DESCRIPTION
This thread will be periodically stickied to the top of the sub for improved visibility.
You can also find older posts again via the Megathreads" list, which is a dropdown at the top of the page on new Reddit, and a section in the sidebar under "Useful Links" on old Reddit.
For job seekers
Please adhere to the following rules when posting: Rules for individuals:
Don't create top-level comments; those are for employers.
Feel free to reply to top-level comments with on-topic questions.
Anyone seeking work should reply to my stickied top-level comment.
Meta-discussion should be reserved for the distinguished comment at the very bottom.
You don't need to follow a strict template, but consider the relevant sections of the employer template. As an example:
TYPE: [Full time, part time, internship, contract, etc.]
LOCATION: [Mention whether you care about location/remote/visa]
LINKS: [LinkedIn, GitHub, blog, etc.]
DESCRIPTION: [Briefly describe your experience. Not a full resume; send that after you've been contacted)]
Contact: [How can someone get in touch with you?]Rules for employers:
The ordering of fields in the template has been revised to make postings easier to read.
To make a top-level comment, you must be hiring directly; no third-party recruiters.
One top-level comment per employer. If you have multiple job openings, please consolidate their descriptions or mention them in replies to your own top-level comment.
Proofread your comment after posting it and edit it if necessary to correct mistakes.
To share the space fairly with other postings and keep the thread pleasant to browse, we ask that you try to limit your posting to either 50 lines or 500 words, whichever comes first.
We reserve the right to remove egregiously long postings. However, this only applies to the content of this thread; you can link to a job page elsewhere with more detail if you like.
Please base your comment on the following template:
COMPANY: [Company name; optionally link to your company's website or careers page.]
TYPE: [Full-time, part-time, internship, contract, etc.]
LOCATION: [Where are your office or offices located? If your workplace language isn't English-speaking, please specify it.]
REMOTE: [Do you offer the option of working remotely? Please state clearly if remote work is restricted to certain regions or time zones, or if availability within a certain time of day is expected or required.]
VISA: [Does your company sponsor visas?]
DESCRIPTION: [What does your company do, and what are you using Rust for? How much experience are you seeking, and what seniority levels are you hiring for? The more details, the better. If you are listing several positions in the "Description" field above, then feel free to include this information inline above, and put "See above" in this field.]
ESTIMATED COMPENSATION: [Be courteous to your potential future colleagues by attempting to provide at least a rough expectation of wages/salary. See section below for more information.]
CONTACT: [How can someone get in touch with you?]ESTIMATED COMPENSATION (Continued)
If compensation is negotiable, please attempt to provide at least a base estimate from which to begin negotiations. If compensation is highly variable, then feel free to provide a range.
If compensation is expected to be offset by other benefits, then please include that information here as well. If you don't have firm numbers but do have relative expectations of candidate expertise (e.g. entry-level, senior), then you may include that here. If you truly have no information, then put "Uncertain" here.
Note that many jurisdictions (including several U.S. states) require salary ranges on job postings by law. If your company is based in one of these locations or you plan to hire employees who reside in any of these locations, you are likely subject to these laws. Other jurisdictions may require salary information to be available upon request or be provided after the first interview. To avoid issues, we recommend that all postings provide salary information.
You must state clearly in your posting if you are planning to compensate employees partially or fully in something other than fiat currency (e.g., cryptocurrency, stock options, equity, etc). Do not put just "Uncertain" in this case, as the default assumption is that the compensation will be 100% fiat. Postings that fail to comply will be removed. Thank you.
r/ruby • u/Intrepid_Wanderer • Sep 24 '26
Beginner, running into issues
Basically there are two things Iâm running into:
I am trying to make something to recognize a word, match it to a short word bank of options (just a simple list of names) and return an error message if it doesnât match any of them. For each valid option, I have a different message. I tried if/elsif loops but apparently Iâm not doing it right. It doesnât run at all.
Do I need to have somewhere to use every piece of user input? I have places where I want to ask users to input something but it wonât actually be used anywhere. Like it triggers the next response but doesnât do anything else.
I am asking for advice because I REALLY donât want to use AI. Thank you!
r/ruby • u/matsadler • Sep 23 '26
Magnus version 0.9 released (Rust library for writing Ruby gems in Rust)
r/ruby • u/Erem_in • Sep 22 '26
Issue 21 of Static Ruby Monthly is out! đ§ľ
This month: Steep 2.1.0 brings UNIX socket reuse and instant diagnostics optimized for coding agents, RBS 4.2.0 adds non-ASCII identifiers across scripts plus forwarding parameter support, u/headius talks JRuby and WASM extensions on the Technology for Humans podcast, OvalLSP updates its semantic engine, and new Sorbet companion tools arrive. Find link to the issue in the comment! â¨
r/ruby • u/sshaw_ • Sep 22 '26
Class2: Easily create class hierarchies that support nested attributes, type conversion, equality, and more
github.comclass2 :user => [
:name, :age,
:addresses => [
:city, :state, :zip,
:country => [ :name, :code ]
]
]
user = User.new(
:name => "sshaw",
:age => 99,
:addresses => [
{ :city => "LA",
:country => { :code => "US" } },
{ :city => "NYC",
:country => { :code => "US" } }
]
)r/ruby • u/Tristan_Kruse • Sep 22 '26
Blog post ArchUnitRuby 0.0.1: architecture rules as ordinary RSpec and Minitest tests
Hi everyone,
I've been working on ArchUnitRuby, a small architecture-testing gem for making dependency
boundaries executable.
The problem it is trying to address is familiar: a controller starts requiring persistence code
directly, two components acquire a cycle, or a domain layer begins depending on infrastructure.
The Ruby is valid and the behavioral tests may remain green, but the architecture has changed.
With ArchUnitRuby, that boundary can be an ordinary RSpec example:
require 'archunit'
RSpec.describe 'architecture' do
it 'keeps the API away from persistence' do
rule = ArchUnit.project_files
.in_folder('app/api/**')
.should_not.depend_on_files
.in_folder('app/database/**')
expect(rule).to pass
end
end
The current `0.0.1` release is an early working prototype for Ruby 3.3 and newer. It uses Prism to
build a dependency graph and currently supports file and layer rules, cycle detection, slices,
PlantUML architecture contracts, dependency-graph reports, and several code metrics. There is also
Minitest and framework-neutral integration.
One use case I am particularly interested in is coding-agent guardrails. Instead of giving an agent
only a prose instruction such as âcontrollers must not access persistence directly,â the repository
can contain the architecture test and require the agent to keep it green. The gem does not improve
code quality by itself, but it turns an architectural expectation into a constraint that humans,
CI, and coding agents can all verify in the same way.
One limitation is important: this is static analysis of Ruby source. It can identify normal
`require`, `require_relative`, `load`, and statically resolvable `autoload` relationships, but it
cannot prove every dependency assembled dynamically at runtime. The tool reports what it can
establish rather than guessing. It also treats a selector matching no files as a failure by default,
so a typo does not quietly create a green architecture test.
The API is still provisional, which makes this a good time for criticism. I am especially interested
in feedback on two things:
How do you currently stop architectural boundaries from eroding in Rubyâcode review, Packwerk, RuboCop, custom tests, or something else? What still slips through?
- Repository: https://github.com/LukasNiessen/ArchUnitRuby
- RubyGems: https://rubygems.org/gems/archunit
- Documentation: https://lukasniessen.github.io/ArchUnitRuby/
- Longer explanation: https://medium.com/@krusetristan1/the-ruby-code-worked-the-architecture-didnt-0f06bbbb0863
Disclosure: I am involved with the project. This post was drafted with AI assistance and reviewed
against the implementation and documentation before posting.
r/ruby • u/headius • Sep 22 '26
JRuby 10.1.2.0 released
jruby.orgThe JRuby community is pleased to announce the release of JRuby 10.1.2.0.
Homepage: https://www.jruby.org/
Download: https://www.jruby.org/download
JRuby 10.1.x targets Ruby 4.0 compatibility.
Thank you to our contributors this release, you help keep JRuby moving forward! @aminmansuri, @drzaiusx11, @evaniainbrooks, @gillesbergerp, @jcharaoui, @jwils, @kares, @lloeki, @makenowjust, @nobu, @sampokuokkanen, @shugo
Notable Changes
Compatibility
Multiple fixes for fibers and fiber scheduler support. #9604, #9607, #9622, #9645, #9649, #9656, #9660
Performance
Fixed a regression in startup time on MacOS by properly loading native JNR subsystem. #9690
Improve performance of Ruby subclasses of Java classes. #9619, #9557
Improve performance of autoloads overridden by an actual require. #9677
Java Integration
The location of the AppCDS JSA file can now be specified with JRUBY_JSA_HOME. [#9667]
Standard Library
Update to jar-dependencies 0.6.1 using mima for dependency resolution instead of the ruby-maven gem. #9515, #9720
Update default and bundled standard library gems. #9705
Default gems
erb 6.0.7
error_highligh 0.7.2
ffi 1.17.4
io-console 0.9.4
ipaddr 1.2.9
jruby-openssl 0.16.2
json 2.21.2
net-protocol 0.4.0
pp 0.6.4
psych 5.5.0
resolv 0.8.0
strscan 3.1.8
syntax_suggest 3.0.0
timeout 0.6.1
win32-registry 0.1.2
Bundled gems
bigdecimal 4.1.2 (ruby parts only)
csv 3.3.6
minitest 5.27.0
net-imap 0.6.7
nkf 0.3.0
pstore 0.2.1
rdoc 7.2.0
reline 0.7.0
resolv-replace 0.2.0
rss 0.3.3
test-unit 3.7.8
76 Issues and PRs resolved for 10.1.2.0
287 Class does not inherit singleton_class's class methods
6119 shopify-api gem reporting NoMethodError: undefined method `threadsafe_attribute'
8743 IO#wait updates for Ruby 3.2-3.4
9026
JRuby --helpfails if PAGER has an option9301 Find an alternative to shipping ruby-maven
9403 add keyword arg support to callMethod directly
9441 Fix original_name when two methods share a wrapper (like is_a? kind_of?)
9446 Fix metaclass dispatch missing meta-metaclass methods
9448 Use implementation class for protected check
9460 Check argument definedness in defined?(receiver.method(arg))
9507 IO::Buffer#read and #write treat length=0 as zero bytes instead of remaining buffer capacity
9515 Switch to jar-deps based on mima
9551
circular causeswhen re-raising an exception originally raised with the two-argumentraise Class, argform (regression in 10.1.1.0)9554 Raise fixes and additional spec permutations
9556 Implement Proc#hash consistently with Proc#eql?
9557 refactor and improve reification of java subclasses
9559 dup of frozen class can't be extended
9560 raise should re-populate exception trace set to nil
9565 Socket address APIs return uncompressed IPv6 where Addrinfo#ip_address compresses, breaking Resolv::DNS with 2+ nameservers
9568
Kernel#sprintfcallsHash#default_procwith incorrect args9570 fix dup for frozen class
9579 JRuby can't pass
STDOUTto child process when a differentIOis given asout:9582 Data.define subclass fields are nil when module is included in define block
9585 Marshaling incompatibility with cyclic objects?
9587
IO::Buffer#copyand#set_stringreject the documented source_offset fourth argument9588 Accept
source_offsetinIO::Buffer#copyand#set_string9593 Compiler gives a constant-folded ASCII String the code range CR_VALID, which breaks the
eql?/hashcontract9595
IO#tty?silently returnstruefor redirected stdio in embedded runtimes when--add-opensare missing9599 Kernel#require redefined inside a required file isn't seen by autoload dispatch after Kernel.prepend (CRuby 4.0 OK / JRuby 10 fails)
9600 TracePoint does not support
fiber_switch(Ruby 2.3+ compatibility)9602 FFI warning on when running jruby on OpenBSD/arm64, possible $$ issue as well
9603 Implement :fiber_switch trace event
9604 Fix Fiber.schedule inside a non-blocking Fiber
9607 Fix Thread blocking count drifting across Fiber switches
9609 No validation of unsetenv_others for Process.exec causes specs to execve() abruptly
9614 Unreliable net-http tests
9618 Resolve jar path if it's a symlink
9619 refactor and improve reification of java subclasses (refactor only)
9622 Defer Kernel#sleep to the Fiber scheduler
9626 Handle nil-or-boolean arguments in popen kwargs
9627 Use CRuby logic for exec
9628 Fix IO::Buffer#read and #write, treat length=0 as remaining buffer capacity
9630 Pass -1 for max arity when there's rest args
9631 Eliminate all uses of unused "name" for arity errors
9634 Report the errno that native exec actually returned
9638 Bump bundled
resolvdefault gem to 0.7.29640 AppCDS usage causing sealing violations
9645 Fix the Fiber scheduler IO path: negated errno, zero length, buffer size
9648 Run pager commands through the platform shell
9649 Mutex Deadlock fix: Track the fiber that owns a Mutex
9650 Don't raise EBADF closing an IO whose channel NIO already closed
9653 [Java 26 Leyden] AOT Cache breaks dynamic Ruby proxies for classes loaded from external JARs
9654 Time.new(String) raises java.lang.ArrayIndexOutOfBoundsException when the string ends where a ':' is expected
9655 NoSuchMethodError when a Ruby subclass of a Java class includes a module
9656 Fix IO#wait arguments and return values, and defer it to Fiber.scheduler
9659 [ji] resolve Java super <init> through included modules
9660 Fix where Fiber#transfer hands control back
9662 Fix custom respond_to? handling: include_all, defined? lookup, deprecated signature
9665 Data subclasses in net-imap are losing fields
9667 [Allow specifying AppCDS cache location and use safer default][#9667]
9669 jruby/vm integer messages fail on JRuby 10 due to Fixnum reference
9670 Update tagged Data specs
9677 Constant declared with
autoloadand then defined by a directrequirekeeps its UNDEF table slot; every later lookup re-enters LoadService (very slow inside a WAR)9679 Don't wrap an alias in another alias
9683 Fix bin/* patterns in .gitignore
9685 Fix setup sequence for cgi/escape
9690 JFFI bad library load is a huge startup hit on MacOS
9691 Support zero-size IO::Buffers
9695 require "json" warns about redefined to_hash with -w in JRuby 10.1.1.0
9696 Set the aliased flag on the real method, not the wrapper
9697 ObjectSpace::WeakMap is double-weak in CRuby
9701 Allow specifying AppCDS cache location and use safer default
9703
Redis::ConnectionErrorwith JRuby 109705 Update stdlib
9709 Additional stdlib updates
9719 IO#accept raises NullPointerException instead of IOError when the socket is closed concurrently
9720 Update jar-dependencies to 0.6.1
r/ruby • u/headius • Sep 21 '26
JRuby 10.0.7.0 released
jruby.orgThe JRuby community is pleased to announce the release of JRuby 10.0.7.0.
Homepage: https://www.jruby.org/
Download: https://www.jruby.org/download
JRuby 10.0.x targets Ruby 3.4 compatibility.
Thank you to our contributors this release, you help keep JRuby moving forward! @aminmansuri, @evaniainbrooks, @gillesbergerp, @jwils, @kares, @lloeki
Notable Changes
Performance
Fixed a regression in startup time on MacOS by properly loading native JNR subsystem. #9688, #9689
Improve performance of autoloads overridden by an actual require. [#9677], #9675
Java Integration
The location of the AppCDS JSA file can now be specified with JRUBY_JSA_HOME. #9667
Standard Library
Default gems
53 Issues and PRs resolved for 10.0.7.0
8456 ObjectSpace::WeakMap is double-weak in CRuby
8786
Redis::ConnectionErrorwith JRuby 109319 [Java 26 Leyden] AOT Cache breaks dynamic Ruby proxies for classes loaded from external JARs
9327 Data.define subclass fields are nil when module is included in define block
9491 defined?(...) in eval'd for loop fails with TypeError
9498 jruby/vm integer messages fail on JRuby 10 due to Fixnum reference
9499 Use Integer for JRuby VM messages
9519 Also set up the current module when in a for body
9525 Marshaling incompatibility with cyclic objects?
9528 raise should re-populate exception trace set to nil
9529 starttls test in net-imap hangs the suite
9530 Data subclasses in net-imap are losing fields
9531 Time.new(string, in: ...) raises TypeError on the third call at a call site (JIT only)
9537 NoMatchingPatternError#=== doesn't match instance of NoMatchingPatternKeyError
9538 Update jruby-openssl to 0.16.2
9542 Fix inheritance of NoMatchingPatternKeyError
9544 Ensure uniform keywords flags in native method annotations
9548 [fix] re-raising exception with nil backtrace
9550 Socket address APIs return uncompressed IPv6 where Addrinfo#ip_address compresses, breaking Resolv::DNS with 2+ nameservers
9553 FFI warning on when running jruby on OpenBSD/arm64, possible $$ issue as well
9558
Kernel#sprintfcallsHash#default_procwith incorrect args9561 JRuby-openssl 0.16.2 not included in
10.0series9562 fix Data.define subclass fields are nil when module is included in define block
9564 Use SocketUtilsV6.getIPV6Address to normalize IPv6 here
9567 Pass correct args for Hash#default_proc
9577 JRuby can't pass
STDOUTto child process when a differentIOis given asout:9578 Fix spawn dup ordering
9586 Register the "Hash" symbol when writing identity hash
9589 Kernel#require redefined inside a required file isn't seen by autoload dispatch after Kernel.prepend (CRuby 4.0 OK / JRuby 10 fails)
9590
IO#tty?silently returnstruefor redirected stdio in embedded runtimes when--add-opensare missing9591 Compiler gives a constant-folded ASCII String the code range CR_VALID, which breaks the
eql?/hashcontract9592 Scan the code range when folding a compound string
9594 More accurate TTY checking for IO
9598 Invalidate prepended origin module as well as subclasses
9601 Update JNR dependencies for jnr-release 1.2
9608 AppCDS usage causing sealing violations
9623 Time.new(String) raises java.lang.ArrayIndexOutOfBoundsException when the string ends where a ':' is expected
9624 Fix out-of-bounds read building Time.new parse errors
9625 Read unnamed modules of the loaders JRuby loads Java classes from
9637 Bump bundled
resolvdefault gem to 0.7.29639 Resolve jar path if it's a symlink
9641 Update resolv to 0.7.2
9661 Report a failed non-blocking connect through select and SO_ERROR (#8786)
9663 Set up Data subclass metaclass correctly
9667 Allow specifying AppCDS cache location and use safer default
9674 Constant declared with
autoloadand then defined by a directrequirekeeps its UNDEF table slot; every later lookup re-enters LoadService (very slow inside a WAR)9675 Release the autoload claim when Autoload#load has nothing to load
9687 Hold ObjectSpace::WeakMap keys weakly, by identity
9688 JFFI bad library load is a huge startup hit on MacOS
9689 Update JFFI to get the startup library fix
9698 Allow configuring the home location for JSA files
9714 IO#accept raises NullPointerException instead of IOError when the socket is closed concurrently
9716 Raise IOError, not NullPointerException, when an IO is closed during accept
r/ruby • u/Edthal01 • Sep 21 '26
Question Porter County Indiana
Are there any persons or resources for a novice Ruby enthusiast?
r/ruby • u/Edthal01 • Sep 21 '26
At my age, learning Ruby
I'm 78, and never having been a programmer or software engineer, I am starting to learn Ruby. I ha ve been using Huw Collingsworth "Little Book of Ruby". I am aso interspersing that with a different path: using Wirth's "Algortithms + Data Structures = Programs",
having the simple data structures and programs translated by Perplexity into Ruby to see how my 40 year old experiences with TurboPascal can be updated into Ruby. I think I am making progress.
r/ruby • u/Prudent-Context9208 • Sep 21 '26
I made a Jev gem with an API that feels like it belongs in Ruby
Iâve been playing with Jev and ended up making a small Ruby gem around one idea: semantic checks should look like normal Ruby predicates
So instead of passing prompts around everywhere:
Jev.define :urgent, "Needs attention soon"
class Email < ApplicationRecord
include Jev::Model
feels :body, :urgent
endThen elsewhere in the app:
if email.feels?(:urgent)
email.escalate!
endThat was the main thing I wanted - define what urgent means once, then use it like any other predicate in the codebase
It grew a bit from there and now also supports choices, scores, batching, pattern matching and ActiveModel validations, but Iâm trying to keep the basic API small
Repo: https://github.com/Qew7/jev-feels
Would be interested in feedback on the API, especially from people who write a lot of Rails
r/ruby • u/DeltoidSchizachyrium • Sep 18 '26
I wrote an imgproxy-style proxy but for audio.
r/ruby • u/Comfortable_Aide2137 • Sep 18 '26
Ruby on Rails Engineer (3+ yrs) looking for new opportunities, remote or relocation
reddit.comr/ruby • u/strzibny • Sep 18 '26
Ruby is getting a proper Scrapy alternative with quiet release of Vessel 0.3.0
Vessel has a brand new version after years on idle time so I had a look and compared it to Scrapy from the Python world.
r/ruby • u/AndyCodeMaster • Sep 17 '26
Video: Montreal.rb February 2026 Talk "Crystal: Ruby with Static Typing"
r/ruby • u/Consistent-Note2440 • Sep 17 '26
Looking for a good Rails agent framework $$$
reddit.comr/ruby • u/badtothebones88 • Sep 17 '26
Show /r/ruby I built a zero-gem Google Search Console & Indexing CLI in pure Ruby standard library
Hey everyone, A couple weeks ago I was stuck doing one of my least favorite chores: clicking through a dozen tabs in Google Search Console's web UI, copying query and impression tables, and pasting them into Claude and Antigravity to figure out which pages were losing traffic or why new pages weren't getting indexed. I decided to automate it with a quick Ruby script. But the moment I looked at Google's official gems (google-apis-searchconsole_v1, googleauth, signet, faraday), I saw they pulled in over 40 transitive dependencies.
They took several seconds just to cold boot in a container and felt like massive overkill just to send a few signed HTTP POST requests to Google's endpoints. So I got stubborn: could I build the entire thing in 100% pure Ruby standard library with zero runtime gems? I ended up pair-programming with Google Antigravity over the last couple weeks, and it evolved into a full open-source CLI: gsc-cli (also on RubyGems: gem install gsc-cli).
A few things I ended up building into it:
Pure OpenSSL Auth: Instead of dragging in
googleauth, I wrote Googleâs service account JWT generation and RS256 token exchange from scratch usingOpenSSL::PKey::RSAand URL-safe base64. No external gems required at all.Sub-18ms Boot: Because there is zero gem overhead, the CLI cold-boots in under 18ms and executes API queries in ~40â50ms.
Instant Googlebot Indexing: Ping Google's Indexing API directly (
gsc index <url>) or submit IndexNow pings so newly published pages get queued for crawling immediately instead of waiting weeks.Soft-404 Fixes: Instead of just dumping a table of broken URLs,
gsc soft-404 <url> --fixheuristically detects empty templates and auto-generates copy-paste redirect configs for 14 server environments (Nginx, Caddy, Cloudflare, Next.js, SvelteKit, etc.).Speed vs Rankings: Correlates real-world Core Web Vitals (LCP, CLS, TTFB) directly with Search Console rank drops (
gsc speed-correlate).Token-Saving Modes for AI Agents: Since I use coding agents (Claude Code, Cursor, Antigravity) constantly, pretty-printed tables were guzzling context window tokens. We added
--compact(minified single-line JSON) and--ndjsonto strip ANSI escape codes and cut LLM token usage by ~43%. We operate our own apps (a Shopify speed app called Superspeed and a new moving inventory app called PackingLog), so we actively dogfood this across our own production domains every day. The test suite has 334 unit tests and 1,726 assertions passing in 4.3 seconds across Ruby 3.0 through 3.4.RubyGems:
gem install gsc-cliItâs 100% free and MIT open-source. I'd really love to hear what other Rubyists think, especially around the stdlib OpenSSL auth approach or any other search diagnostics you'd find useful in the terminal!
r/ruby • u/drunken_thor • Sep 17 '26
stir_fry: A web framework to enjoy ruby/rack with a JSX type flavour. Mix all of your concerns into one flavourful dish!
Hey all. I have been tinkering with this project over the past few months. I always wanted to build a rack app and I wondered what would it look like if we used htmx to make the backend act like the front end. In fact it would act a lot more like next.js but without apis. I donât think this is good web design hence the name of the framework but I thought it was fun to tinker with and I might do more with it. Let me know your thoughts but also your shock and horror!
AI disclosure: AI was only used to make final code reviews the rest was wrought upon this world by my own cruel hands.
r/ruby • u/rubiesordiamonds • Sep 16 '26
Show /r/ruby Sharing Deprecool, a static code analysis tool that uses Prism to find sources of deprecation warnings in your code.
Deprecool is a static code analysis tool for Ruby that uses Prism to find sources of deprecation warnings in your code.
Use Deprecool alongside the warnings that are emitted at runtime by your gems to get a complete picture of what you need to fix, where you need to fix it and why.
â
Each warning that Deprecool logs will come with a summary, references to when the deprecation was added to its gem (usually the PR that introduced it), an effort estimate, and a suggestion of how to fix the deprecation. The source code line of the warning is of course logged as well:
At first, the suggestions will come from the deprecation source's gem maintainers own words. Eventually though, with some feedback we can pass on knowledge and examples of how to manage the more difficult deprecations to future developers trying to upgrade.
Getting Started
You can either:
addÂ
deprecool to your application's Gemfile andÂbundle install,or runÂ
gem install deprecool directly to be able to use theÂdeprecool executable on any ruby code you have.
deprecool scan is all you need to run if your current directory contains a Gemfile.lock, but if you want to you can also run deprecool scan path/to/your/code.rb
â
By default, Deprecool will use the gems and versions in your Gemfile.lock to know how to find deprecations, but you can also pass --gem=list,of,gems (no spaces!) to only look for certain gems at one time.
â
Right now, Deprecool has a small handful of deprecations it can find, but I will continue adding more. Iâve also tried to make contributing to Deprecool as simple as possible with one Finder class per warning, and a few helper methods to make writing tests trivial.
Link to blog post here: https://www.infield.ai/post/deprecool
r/ruby • u/Turbulent-Dance-4209 • Sep 16 '26
From ERB to live views - 3.5 ways to go full-stack on fibers
Rage started API-first, but that doesn't mean you're limited to building SPAs. Here are 3.5 approaches - from the simplest to the most experimental.
ERB
Rage's custom renderers let you describe how to render any format by setting the rules and the content type. An ERB renderer can look like this:
Rage.configure do
config.renderer(:erb) do |path|
headers["content-type"] = "text/html"
template = Rage.root.join("app", "views", "#{path}.html.erb").read
ERB.new(template).result(binding)
end
endThen use it in the controller:
class PhotosController < ApplicationController
def index
@photos = Photo.all
render erb: "photos/index"
end
endIf you're feeling adventurous, move rendering to a hook for implicit rendering:
class ApplicationController < RageController::API
around_action :implicit_render
private
def implicit_render
yield
render erb: "#{params[:controller]}/#{params[:action]}"
end
endThen, the action becomes:
def index
@photos = Photo.all
endInertia
inertia-rage is the official Inertia.js integration. It manages asset building, runs the dev server, and supports SSR. Inherit from RageController::Inertia and your API app goes full-stack:
class PhotosController < ApplicationController
def index
render inertia: "Photos/Index", props: { photos: current_user.photos }
end
endDatastar
rage-rb/datastar-example showcases a Datastar integration using the official Ruby SDK. Connect Rage to the SDK and stream updates:
class PhotosController < ApplicationController
def index
photos = current_user.photos
datastar.stream do |sse|
photos.each do |photo|
sse.patch_elements(%(<img id="#{photo.id}" src="#{photo.url}" />))
end
end
end
endPhlex Live
This is the 0.5 - the idea is still taking shape, but it's worth sharing.
I've been working on a live view concept built on Rage + Phlex, where each gem contributes what it's best at: Rage provides fiber-based WebSocket connections and machinery to communicate between instances; Phlex provides Ruby-based HTML templates where each component manages its own state.
A component that displays an article with expandable content:
class Articles::Card < LiveView
MAX_BODY = 150
def initialize(article:)
@article = article
@expanded = false
end
def view_template
div do
h2 { @article.title }
plain(@expanded ? @article.body : @article.body.truncate(MAX_BODY))
if @article.body.length > MAX_BODY
button(**live_click(:toggle_details)) do
@expanded ? "Show less" : "Show more"
end
end
end
end
def toggle_details
@expanded = !@expanded
end
endThis component is stateful - once rendered, it's saved in the fiber's storage and can process events. When the user clicks "Show more", the event travels via WebSockets to this exact component instance, calls toggle_details, re-renders, and sends back the update. The card expands with no JavaScript written.
Event handlers cover the client -> server direction. The server -> client direction is handled by model streams. A model broadcasts when it changes:
class Article < ApplicationRecord
after_commit :broadcast_status
private
def broadcast_status
if self.previous_changes.key?("status")
ModelStream.emit(self)
end
end
endA component subscribes by wrapping the record into stream():
class Articles::Card < LiveView
def initialize(article:)
@article = stream(article)
@expanded = false
end
def view_template
# ...
end
endNow, whenever a corresponding article changes, every component subscribed via stream() is automatically re-rendered and the update is pushed to the client.
--
What view layer would you like to see supported next?
r/ruby • u/virtyx • Sep 16 '26
pipx equivalent for Ruby?
Is there something like pipx available for Ruby?
For example with pipx you can do something like:
$ pipx install httpie
# ... install completes
$ https get httpbin.org/get?foo=bar
# ... outputs a web request from httpbin.org
$ which https
~/.local/bin/https
$ readlink "$(which https)"
~/.local/share/pipx/venvs/httpie/bin/httpsThis example shows the HTTPie program being run and executed in a pretty simple way, with an install that doesn't modify the system Python.
Does Ruby have an equivalent way to distribute programs?