All Episodes

September 16, 2025 • 63 mins

Ruby core team member Aaron Patterson (tenderlove) takes us deep into the cutting edge of Ruby's performance frontier in this technical exploration of how one of the world's most beloved programming languages continues to evolve.

At Shopify, Aaron works on two transformative projects: ZJIT, a method-based JIT compiler that builds on YJIT's success by optimizing register allocation to reduce memory spills, and enhanced Ractor support to enable true CPU parallelism in Ruby applications. He explains the fundamental differences between these approaches - ZJIT makes single CPU utilization more efficient, while Ractors allow Ruby code to run across multiple CPUs simultaneously.

The conversation reveals how real business needs drive language development. Shopify's production workloads unpredictably alternate between CPU-bound and IO-bound tasks, creating resource utilization challenges. Aaron's team aims to build auto-scaling web server infrastructure using Ractors that can dynamically adjust to workload characteristics - potentially revolutionizing how Ruby applications handle variable traffic patterns.

For developers interested in contributing to Rails, Aaron offers practical advice: start reading the source code, understand the architecture, and look for ways to improve it. He shares insights on the challenges of making Rails Ractor-safe, particularly around passing lambdas between Ractors while maintaining memory safety.

The episode concludes with a delightful tangent into Aaron's latest hardware project - building a color temperature sensor for camera calibration that combines his photography hobby with his programming expertise. True to form, even his leisure activities inevitably transform into coding projects.

Whether you're a seasoned Ruby developer or simply curious about language design and performance optimization, Aaron's unique blend of deep technical knowledge and playful enthusiasm makes this an engaging journey through Ruby's exciting future.

Send us some love.

Honeybadger
Honeybadger is an application health monitoring tool built by developers for developers.

Judoscale
Autoscaling that actually works. Take control of your cloud hosting.

Disclaimer: This post contains affiliate links. If you make a purchase, I may receive a commission at no extra cost to you.

Support the show

Mark as Played
Transcript

Episode Transcript

Available transcripts are automatically generated. Complete accuracy is not guaranteed.
Speaker 1 (00:01):
Hello everyone, welcome to another episode of
Code and the Code Encoders.
Who Code it?
I'm your host, drew Bragg, andI'm joined today by the man, the
myth, the legend, tenderlove,himself, mr Aaron Patterson.
Aaron, for anyone who somehowdoesn't know who you are, would
you please do a briefintroduction for the listeners?

Speaker 2 (00:19):
My name is Aaron Patterson.
I do go by Tenderlove on theinternet.
I am on the Ruby core team andthe Rails core team.
I've been programming Ruby,let's say professionally, since
when I say professionally I meangetting paid to do it.
That doesn't mean I'mprofessional at it.

(00:39):
I don't know.
I've been doing Ruby as a jobsince 2008 or so I've been doing
it for quite a while.
I don't know.
I've been doing Ruby as a jobsince 2008 or so, so I've been
doing it for quite a while.
Yeah, I don't know.
I have a lot of open sourcecode and I write a lot of code
and stuff.

Speaker 1 (00:51):
Write a lot of code YouTube video, blog posts.
Occasionally you do a littlebit of everything.
Yes, in all the ways that mostlisteners interact with Ruby
you've touched, whether it beRails or Ruby itself.
So the way that this will workfor anyone new to the show is
I'm going to ask Aaron threequestions.
I'm going to ask him what he'sworking on, what kind of

(01:13):
blockers he has.
He can talk about a recentblocker he had if he doesn't
have a current one.
And then the last question willbe for him to share something
cool, new or interesting that hehas recently discovered built.
This is a little bit of aloaded question for someone like
Aaron, but it'll be a great oneonce we get there.
So you are a busy man workingon a lot of cool stuff.
So when someone asks you whatare you working on, how would

(01:35):
you answer that I am working onmany things.
I don't know.

Speaker 2 (01:40):
It also depends on who it is.
If someone I don't know isasking me what I'm working on,
I'll just be like computer stuff, I don't know.

Speaker 1 (01:47):
That's fair.
Not printer, computer stuff,but computer stuff.
Yes, okay, well for your dayjob what are you working on?

Speaker 2 (01:56):
Sure, yes, I think I have an answer for your audience
, of course.
Okay, so at work, I'm workingon two main projects at work.
One of them is ZJIT, which is anew JIT compiler for CRuby, and
then one of them is betterRactor support in Ruby, and
those are the two main thingsthat I'm really focusing on at

(02:17):
work at the moment to both ofthose because I am interested in
both of those.

Speaker 1 (02:22):
I'm curious on your team at work, matt Shopify.
How do you get that kind ofwork?
Because I think a lot of uswork on application development,
so we're building a Rails app,so it'll be okay.
Hey, this is the slice of theapplication that we want to
build next, or this is thefeedback that we've gotten On a
team like yours, where you'realmost building an ecosystem in

(02:45):
a way, how does that work?
Come down to you.

Speaker 2 (02:49):
All of our work is driven by the needs of the
business.
The thing that we're trying toaim for is better utilization of
our production machines.
So whatever we can do to betterutilize our production machines
, that's what we're aiming for,and our team happens to focus on
the language level of thatparticular problem.
That's kind of how we get there.

(03:11):
Yeah, of course, like ZJIT isfor making sure we use a single
CPU faster Not faster, but morelike more CPU and then Ractor
concurrency or parallelism workis like how do we use all of the
CPUs?
So that's kind of how they gotogether.

Speaker 1 (03:30):
That's actually a really cool description of the
two different projects and howalmost different, in a way, they
are.
They're serving two differentgoals.
How do you balance that?
Sometimes, I think, at least inmy work sometimes jumping
between very backend heavy workand very frontend heavy work,
especially with it beinggenerally two different

(03:51):
languages, two different ways ofthinking about building the
thing.
Sometimes it can be really hardto jump between those two
different things.
How do you deal with that inprojects where it's like single
CPU, concurrent CPU usage?

Speaker 2 (04:07):
It is pretty difficult At work.
We have two different teams.
We have a team that'sspecifically working on Ractor
stuff.
They're focused on that.
We have another team that'sworking on the JIT compiler
stuff and they're focused onthat, and I kind of move between
both teams.
I'm trying to help with anytype of blockers that they have
or just doing development.
Wherever we're short, I'mtrying to fill in on those

(04:29):
particular things and doing thecontext switching.
It's hard.
I don't have a good answer foryou.

Speaker 1 (04:40):
That's fine.
Maybe you had like a hey,here's how I do it at my level.
I've been doing this forever,so I've figured out a trick, or
hey, it just never gets easier.

Speaker 2 (04:48):
You just do the best you can applicable to the other
projects, because both of theseprojects they're sprawling
throughout the internals of ruby, like they touch everything in

(05:10):
ruby internals.
So like if you work on stuff inractors you're going to be
touching, like the garbagecollector, for example.
And when you're working on thejit compiler too, you also have
to touch the garbage collectorin that case as well.
Working on the JIT compiler too, you also have to touch a
garbage collector in that caseas well.
Same with the virtual machine.

(05:31):
All these things kind of gettied together so you can take
the knowledge from one and applyit to the other.
It's really just like thespecialized sections where it's
maybe kind of difficult.

Speaker 1 (05:38):
So in Ruby we already have YJIT.
Yeah, a lot of people are usingYJIT and it's been pretty
successful.
That, if I'm rememberingcorrectly, was originally
written in C and then written inRust.
Yeah, that's correct.
Yes, so I guess.
Two questions what is ZJIT ifwe already have YJIT, and then
what is it written in?

Speaker 2 (05:59):
We'll start with the second one.
First, zjit is also written inRust, because that's just an
easier one to answer.
So YJIT is an awesome project.
It's based on Maxime, it'sbased on her PhD work.
It's really really amazing,really great.
It's what we call a basic blockversioning JIT compiler and I

(06:22):
think it's her new research.
This is her thing, and what itis is.
If you imagine, most JIT compand I think it's her new
research, this is her thing.
What it is is, if you imagine,most JIT compilers are what we
call method-based, where they'lltake a whole method and they'll
compile the entire method andthen you're done, whereas lazy
basic block versioning is evenmore lazy than that.
For example, let's say we havean if statement in your code and

(06:46):
only one side of the ifstatement is taken, the JIT
compiler, yjit, will onlycompile that side of the if
statement.
So, whereas a method-basedcompiler will compile both sides
of the if statement and whetheror not both sides are used, the
method-based compiler willcompile both, whereas YJIT will

(07:07):
only compile the single side.
And where that's very, veryhelpful is that warm-up speeds
are very low because we'recompiling literally compiling
less code.
It's very, very lazy.
The other nice thing is anytypes that we discover at
runtime.
So when it's compiling codeit'll take a look at the objects
that came in and check theirtypes and then it'll generate

(07:29):
machine code based on thosetypes.
It's able to propagate thosetypes through the system and
generate more machine codespecialized based on those types
and not do type checking overand over.
So you can imagine like everytime you call a method on an
object it's got to check whattype that thing is in a normal
program, whereas in YJIT when itdiscovers that type on the

(07:53):
first one it'll do the typecheck.
The first method call it'll dothe type check, but the second
one it's like oh, I already knowwhat that type is, I'm not
going to bother doing it asecond time.
Zjit is just a method-basedcompiler.
It is more traditional JITcompiler, the idea being that

(08:14):
we're taking the things that welearned from developing YJIT and
implementing it and bringingthose into ZJIT and seeing if we
can get an even bigger speedboost out of that.
Sorry, that's a lot of stuff.

Speaker 1 (08:21):
No, I mean it's good, especially if folks aren't
familiar with JIT compilers atall, yjit especially being a
very new way of doing JITcompilation.
And it was interesting that youbrought up the boot time.
I could be remembering thisincorrectly, but if I remember
correctly, that was sort of likethe problem with TruffleRuby.

(08:44):
If I remember correctly, thatwas sort of like the problem
with TruffleRuby.
It's like TruffleRuby wasfaster but it took significantly
longer to boot because it didsome of that work behind the
scenes.

Speaker 2 (08:51):
Yeah, yeah, truffleruby takes a really,
really long time to warm up.
And going back to how thebusiness drives the things that
we develop, we deploy all thetime.
We're deploying over and overagain, and I think this is a
pretty common thing inbusinesses these days.
So, like that, warm-up speedmatters.
We can't just let it sit thereand warm up for hours or
whatever it's got to be like now.

(09:12):
So warm-up speed is very, veryimportant to us.

Speaker 1 (09:16):
So because of how the two compilers work differently,
ZJIT will take longer to warmup than YJIT, but because it
does the whole method block, itmay be faster?

Speaker 2 (09:31):
Yeah, that's a great question.
Let's try and break down theadvantages of a method-based
compiler.
So the advantages of YJIT, ofcourse, are that we compile less
stuff, when the advantages ofan entire method-based compiler
are.
When you compile a method, webreak the code down into what we
call basic blocks.
These basic blocks areessentially chunks of code that

(09:52):
don't have any branches in them.
So if you think about an ifstatement, an if statement is
going to have, say, four basicblocks.
We're going to have one at thetop all the code that's executed
before the if statement.
Basic blocks we're going tohave one at the top all the code
that's executed before the ifstatement.
We have two blocks one thatrepresents one side of the if
statement and the other thatrepresents the other side, and
then we have a fourth block downat the bottom where those two

(10:15):
blocks join.
So you can imagine kind of adiamond shape.
An issue that comes in isregister allocation.
In our CPUs we only have acertain number of registers that
we can use and anytime we havevalues, if we can keep them in
register.
The longer that we can keep themin register, the faster our
program will be, because readinga value from a register is much

(10:36):
faster than reading it frommemory.
So an issue with a lazy basicblock versioning thing type
compiler is that when youcompile one side of that branch
we can't know necessarily whatvalues will land in a particular
register.
We have to get those registersto align all the way through

(10:57):
that diamond shape and the onlyway we can see where those
registers land is if we compiledthe entire method, where those
registers land is, if wecompiled the entire method.
So going through themachinations or whatever process
we have to do of getting thosevalues to line up, that means we
end up spilling a lot morestuff to memory.
Spilling is a term in JITcompilers or compilers just
meaning we take stuff from theCPU registers and we put it into

(11:20):
memory.
We spill it to memory.
So what we want to do is reducespills as much as possible, and
a full like method-basedcompiler is able to reduce
spills much more than a lbbvcompiler.
So those are the advantagesthat we're looking for.

Speaker 1 (11:37):
We're hoping to get out of this method-based jit is
that we'll be able to reducespills so is this a situation
where you're taking what you'velearned from building YGIT,
building ZGIT and then ZGIT willbe the thing, or is this a
we're building ZGIT with thelearnings from YGIT, but we're

(11:57):
going to use both, or is thatnot how?

Speaker 2 (12:01):
It could go either way we expect.
So we do expect that ZJITwarmup may be slower than YJIT,
but we don't expect it to besignificantly slower.
We're hoping that it's going tobe in the range that it's like
nobody cares.
But if it's outside that range,like if it's very slow, we
could imagine ourselves having amulti-tier compiler where it's

(12:23):
like, okay, we'll start off withyjit and we get that fast
warm-up or low warm-up time andthen, as the program is running,
since we have more time, it'slike oh, okay, now we'll use
zjit to compile the method andget even faster code.
So we could end up in a worldlike that.
But just for simplicity's sakewe're hoping not to.

(12:43):
We want to have z-jits warm-uptime be so fast that that's just
the one and we just use thatone.

Speaker 1 (12:50):
But it really just depends on how the numbers shake
out so I guess the next logicalquestion is after z-jit does it
become a-jit or is there a newlike?
Like one JIT I'm joking.

Speaker 2 (13:07):
YJIT was essentially like that pattern of like yet
another JIT compiler right, yeah, yet another JIT compiler, yes,
and then ZJIT is just like well, we're making it.

Speaker 1 (13:15):
Yeah, it's after Y.

Speaker 2 (13:17):
Got.
It Should have started out at A.

Speaker 1 (13:22):
I don't know.
It's interesting because you'reworking on Ruby, right?
You're working on Rubyimprovement, but you're not
actually writing Ruby to do so,right?
You're writing Rust.
Yes, this is a pattern that Ishouldn't have been as
unexpected as it was for me whenI heard people working on Ruby
were working on C right, Becausethey're working in C to work on

(13:43):
Ruby.
You're working in Rust to workon Ruby.
We're working on C right,Because they're working in C to
work on Ruby.
You're working in Rust to workon Ruby's JIT compiler.
What was learning Rust like?

Speaker 2 (13:54):
I'm still learning it .
I hate Rust.
I'm so sorry.
It's like I don't like it.

Speaker 1 (13:59):
It's not a good language.
Yeah, I mean I was going tokind of go into like Ruby's not
your only language.
You've been doing this for awhile, so I'm sure.
So I didn't know if learningRust wasn't that hard because
you've worked in languages likeRust or like you just love Ruby
and friggin.
Rust is nothing like it andthis is annoying, or Rust is
fine it's just like it's fine.

Speaker 2 (14:19):
It's an okay language .
It's better than C, but the baris like so low.
Yeah, it's better than c, butthe bar is like so low.
Yeah, yeah, it's a very, verylow bar.
If I were to pick a systemslanguage to use for this project
, I would actually pick zig.
I love zig a lot.
It's a very, very, very goodlanguage.
Biggest problem with zig is thelanguage stability.

(14:40):
Like I could never in goodconscience recommend Zig as a
language for a long-term project.
You know what I'm saying.
So I think it's just becauseRust is trying to save you from
everything.
But sometimes I'm like look, Iknow what I'm doing, please just

(15:01):
like leave me alone.
And like Zig gives me that.
It's like just enoughhandholding.
But if I want to do my ownthing, I can and it's really
fine.
And I can understand how peoplewould like that.
They want to do systemsprogramming and they don't want
to have to deal with seg viewsor any of those particular
problems.

(15:21):
In this case, like in a JITcompiler, a JIT compiler is
essentially generating machinecode at runtime and no amount of
safety checks in Rust are goingto ensure that that machine
code that we generated atruntime is safe.
It can't make that guarantee.
We're still debugging segmeetsLike it didn't save us from that

(15:45):
.

Speaker 1 (15:47):
So what do we get out of it?
That's my next question is why,then?
I feel like when I had KevinNewton on, he talked a little
bit about the reasoning.
That was a while ago, so I'lljust ask you to reiterate why go
with Rust instead of?
I mean, you said you like itbetter than C, so I guess
there's that reason.

Speaker 2 (16:05):
Huge, huge, big reason.
A JIT compiler is like it's abig beast.
It's a lot of stuff Like a lotof code you got to put together
and as far as like codeorganization goes, like C is
terrible.
Rust is way, way better at that.
You can organize your codenicely.
It's much easier to understandand find things.
It's easier to makeabstractions than C, so you can

(16:27):
make nice abstractions.
You don't have to know all theother stuff that's going on
behind the scenes.
So I think it's like for whatwe're doing, it's a very
appropriate choice.
For sure.
It just doesn't mean that it'smy favorite.

Speaker 1 (16:43):
This is one project ZJITIT and working in Rust and
then flip the coin and you goover to Ractor work.
Yeah, and I guess we got torepeat some of the questions of
like, if anybody's unfamiliarwith Ractors, let's talk a
little bit about what Ractors doin Ruby.
And then do you get to writeRuby now, or we still?

(17:04):
Are we back in Sealand?
Ruby now?
Are we back in Sealand or?

Speaker 2 (17:06):
is it something else?
Back in Sealand.
Back in Sealand.

Speaker 1 (17:08):
You're working on Ruby.
You are not touching Ruby.
Got it no.

Speaker 2 (17:14):
So for folks that are listening to your program that
don't know, ruby has a GVLsimilar to Python, which means
that anytime you try to run CPUintensive code, it means that
Ruby can only use one CPU at atime.
You know if you need to runFibonacci or whatever in
parallel, it's not going tohappen.
You can't do it.
There are some things we can doin parallel, like, for example,

(17:37):
you can do multiple IOs inparallel so you can like read
from a socket in parallel.
That'll work.
But any type of CPU-bound workyou can't do that in parallel,
and that's all due to the GVL.
So Ruby already has fibers, italready has threads, but the

(17:58):
threads and fibers only allow usto have IO-level parallelism
where we want CPU-levelparallelism, and Ractor solves
this issue.
So Ractors have their own GVL,but you can have multiple of
them running in parallel.
So just imagine, like I don'tknow, you get all the safety of

(18:18):
a GVL but you get parallelismtoo.
So that's what we're working on.
Ractors are different fromthreads.
It's kind of like I think thename came from like actors.
It's like an actor-based system.
It's ruby actors, ractors.
So the main thing with them isthey put a huge restriction on
the data that you can share.

(18:39):
If you want to pass a valuebetween ractors, it's going to
copy the whole thing, unless thewhole thing is read-only.
If it's read-only, it'll justshare a reference, but if it's
not read-only, it's going tocopy it before it passes it to
the other thing.
I mean, that's kind of an issue, but not really.
If you know about the data thatyou're passing between the

(18:59):
things, it's not too cumbersometo say I need to make sure
everything's frozen.
Where the issues come in,though, is like lambdas, for
example.
This is a subtle problem, butpeople will run into it for sure
, and they'll just be like Idon't understand why this is a
problem.
Let me, like, set the stage foryou.

(19:21):
You've done define methodbefore, probably, and you give
define method a block, and thatblock captures the surrounding
environment, right?
So if you have a local variabledefined outside of that block,
inside the block, you can accessthat local variable, and it's
because the block captured theenvironment that was surrounding

(19:43):
the block.
I feel like every I don't knowtwo or three years, people
discover a memory leak in theirapplication and it's due to this
.
It's because they made a giantobject and then they did a
defined method or something andnow that giant object's sticking
around in their heap foreverand ever and it's because the
lambda captured the environment.
So let's say your definedmethod method with a block,

(20:07):
let's say it writes to thatlocal variable.
It can do that, that's a thingit can do and that's a form of
mutation in mutating thesurrounding environment.
So what that means is thatmethods that are defined method
with a block, you can't callthem inside of a Ractor because
they could mutate thatsurrounding environment and

(20:28):
Ractors only allow immutableobjects to be shared between
them.
We have these weird subtleproblems where you're like why
can't I just this is a definedmethod, why can't I just use
this thing?
So we're trying to solveproblems like that.
The other types of problemswe're trying to solve are just
bottlenecks inside of Rubyitself.

(20:49):
I'll describe to you myfavorite one so far the John fix
.
This is a great bug and it'svery easy for people to
understand the issue.
So if you take JSON input andyou're parsing a hash, for
example, and the hash has a keylike a string key maybe it's
just like hello points to world,so you have hello as a key.

(21:09):
But let's say you parse thatJSON twice.
So you have two hashes, bothwith the same contents hello
world.
If you get the keys out of thehash, that string, hello.
So those two strings, hello.
Those are identical strings,and I don't just mean the
contents of the string.
If you check the object ID ofthem, it's exactly precisely the

(21:32):
same object and I think mostpeople probably know about this.
Think about how that worksunder the hood.
How do we do that?
Because we're parsing twodifferent JSON documents.
There has to be some sort ofdata structure that how do I say
this makes them unique.
You know what I'm saying?
Like looks it up and says likeokay, that's the hello string, I

(21:55):
got to go get the same one andlike stick it into this hash.
So we have like a global hashtable it's global inside of the
VM, a global hash table where welook up those strings then
insert them into the hash.
So you can imagine, if you havetwo different Ractors that are
both trying to parse JSON at thesame time, there's going to be
contention on that global hashtable.

(22:16):
So we had an issue filed Idon't remember how long ago it
was, but a while ago wheresomebody was like yeah, if I try
to parse JSON in Ractors, it'sslower.
It's literally slower than if Ido it without Ractors.
I could do it in serial andit's faster than doing it with

(22:38):
Ractors and it's because of thecontention on that global hash
table.
So John implemented a fix whichwas a lock-free data structure,
a lock-free hash table, so wecould eliminate that contention
and now it's faster, like it'smuch, much faster to parse JSON
between reactors and we'refinding different bottlenecks
like these global datastructures within the virtual

(22:59):
machine.
So it's like kind oftwo-pronged approach.
One is fixing language features, like that defined method thing
that I was talking aboutearlier, and the other one is
bottlenecks within the system.

Speaker 1 (23:12):
I feel like in Ruby I mean, ruby is a very mature
language now, so a lot of theevery version is less holy crap.
Look at this new feature andmore like subtle little things
that, depending on the type ofprogramming you're doing, might
not be anything that you'regoing to use, but something like

(23:33):
we're moving a lot closer tofrozen string literals and being
the default and we got the newdata object, which is
essentially just an immutableobject.
Is that work because of thework that you're doing in
Ractors, where you're kind oflike trying to create a better,
less mutable environment forRactors to run in?

(23:56):
Or is it just so happened?
Like you said, we want lessmutable stuff and like, yeah,
this stuff's here too.
They have nothing to do withone another.

Speaker 2 (24:04):
And I'm just reading into it.
Yeah, it's not particularlyrelated.
No, so the Ractor thing iscoming in.
Moving back to the businessagain, talking about where our
stuff comes from, we have anapplication at work.
The workload on it is random.
When a request comes in, wedon't know if it's going to be
mostly IO bound or if it's goingto be mostly CPU bound.

(24:24):
It could be either IO bound orif it's going to be mostly CPU
bound.
It could be either.
We don't know, and it's a hugeproblem.
So imagine you have anapplication like that and you're
using a forking web server.
So typically what you do isyou'd pre-fork, maybe I don't
know 1.5 times or 1.25 times thenumber of CPUs.
You have some number, somecoefficient, and let's say you

(24:45):
have this random workload andall the requests come in, but
they all happen to be IO bound.
So in that case, like, let'ssay, you had a machine with 10
processors, just to make themath easy, and you're doing 1.5.
So you have 15 processes,you're servicing 15 IO bound
requests in parallel, but themachine if you look at CPU

(25:09):
utilization on the machine, it'slike nothing because they're
all IO-bound.
You could be serving more.
You could be serving more,you're capped at 15.
Now, on the other end of thespectrum, let's say you have all
CPU-bound requests coming inand you're trying to service 15
CPUpu bound requests on amachine that only has 10 cpus.

(25:29):
Now your latency is gettingmessed up because those 15
processes are contending, alltrying to get cpu time.
How do we solve this problem?
What we'd like to do is we'dlike to have a way to
automatically scale the webserver up and down so that we
can say like oh, we have morecapacity on this machine.

(25:52):
We're serving 15 IO boundrequests.
We can spin up another and takemore, take more, right?
Or hey, we're serving 10 CPUbound requests right now.
I don't want it, don't give meanything, please.
Don't give me anything, please.
So we would like to be able tospin that up and have the web
server automatically scale towhatever the load is on that
particular machine, and we thinkwe can do it better with

(26:15):
Ractors than with any other.
Concurrency primitive.
That's like the ultimate,ultimate goal.
That's the world we'd like toget to.
Of course we're not like it'sgoing to.
We'd like to get to.

Speaker 1 (26:27):
Of course we're not like going to take a while to
get there.

Speaker 2 (26:31):
Yeah, yeah, yeah.
So that's kind of the thingthat we're aiming for and what
we're trying to drive theseparticular features.
So it's not to do necessarilywith that read-only data
structures, but those for surehelp.

Speaker 1 (26:43):
So they help, but they weren't born of this
project, they just help thisproject along.
Yeah, yeah, yeah.
How often does it happen thatyou potentially have a larger
project and you get shoot-offslike what I just described?
That's completely inaccurate,but I'm hoping it does actually
happen in your work, whereyou're like, hey, we got to do

(27:04):
like X thing and it's like cool,well, we can shoot this off,
like this can become its ownfeature within Ruby, so let's go
build that thing and then thesemultiple other things get done
and then that makes this mainproject easier.
Does that happen at languagelevel, like it does sometimes in
application development?

Speaker 2 (27:23):
or is it not?
I feel like it happens all thetime.
It's just a very small scale.
Every single project seems likean offshoot is basically what
it is, because the project'svery nebulous.
It's like oh okay, we need tomake ractors better.

Speaker 1 (27:36):
It's like okay, that's so well defined.

Speaker 2 (27:39):
I love it like what does it mean exactly?
So we end up finding these likeweird bottlenecks.
I mean, a huge one that wehaven't talked about at all is
garbage collection.
So that's a thing.
It's like, oh okay, well, arewe going to dedicate resources
to working on GC for thisparticular thing, because GC is
going to be a bottleneck as well?
Just to answer that question,we are not putting any people on

(28:02):
GC at the moment.
Koichi is working on aper-ractor garbage collector.
So the issue just to tell folkswhat the problem is I was
talking earlier about we'refinding bottlenecks on global
data structures.
So if you have any global datastructures, of course those
multiple threads are going tocontend on those data structures

(28:25):
.
And one thing that is a globaldata structure is our garbage
collector.
All Ractors allocate out of thesame garbage collector.
So you can imagine we get to apoint where it's like, oh, we're
contending on allocatingobjects or freeing objects or
whatever.
So what we would like to haveis the GC per Ractor, and

(28:46):
Kuiti's been working on that.
We're hoping that's going toship in Ruby 3.5.
That'll help a lot.
But yeah, we end up with weirdoffshoots like that.
The define method problem wewere talking about earlier.
We've got a bug to deal withthat, the way that we can
support that.
We're working on something likethat.

(29:07):
So it seems like if you justlooked at the ticket from the
outside, it would seem likereally weird, like why, why are
you doing this?
But it's all to support thisparticular thing.
In that case, I don't know ifyou're listening to, care, I'm
gonna say it anyway.
Say I'm going to say it anyway.
Say it anyway, I'll say itanyway.
What we want to do is, when weshare a Lambda sharing Lambdas

(29:30):
between reactors is a huge pain.
It's a huge pain.
I feel it's a thing peoplewould want to do.
John and I have tried to makeRails Ractor safe.
We've tried to do it just as away to figure out what stuff we
need to work on, because a lotof stuff we have to do is
discovery.
We're trying to eat an elephanthere, right.

(29:50):
Where do you start?
We have no idea.
So we're just trying to dodiscovery.
I think the first hiccup welanded on was like oh my
goodness, we've got all theselambdas that we can't share.
For example, the router haslambdas.
Every time you're doing specialstuff in the router, it's going
to have lambdas.
We got all the access support,callbacks, whatever.

(30:12):
Those are all lambdas too andthey're shared throughout the
entire application, so thosehave to be passed around via
Ractors.
The plan so far is we can detectwhen a lambda tries to access
an outer environment, so we candetect when it's reading.

(30:33):
Okay, we can also detect whenit's writing, so we can detect
when you do write.
So what the plan is is if youdo a write to the environment,
we're going to raise anexception, so you can't share
that.
But if you do a read, that'sfine.
So like if're going to raise anexception and say you can't
share that, but if you do a read, that's fine.
So if you want to capture anenvironment, you do a bunch of
calculations or whatever and youwant to cache that, essentially

(30:55):
by passing a lambda around.
Good on, you, have fun, itshould work fine.
But we also need to detectcases where maybe you write to
the local variable after youdeclare the lambda.
This would manifest as a racecondition essentially if you
allowed that.
But we can detect that case aswell.
So we're trying to work on likeloosening the restrictions for

(31:17):
these things, where it's like,if it's read, only if you're
just making a lambda that's justreading data.
We're good, no problems.
Right now it's very, veryrestrictive.
It's basically like no can't doit.
So and that's, of course, anon-starter.
I mean, think about like aSinatra app.
The Sinatra app, it's allLambdas, right.

(31:39):
You'd never be able to write aRactor-based web server for it.
It just wouldn't work, justcan't do it.
So yeah, wouldn't work, justcan't do it.
So yeah, that's fun, though.
I enjoy it it's fun.

Speaker 1 (31:47):
I have a slight headache just trying to keep it
all in my head.
But yeah, sure, fun, let's gowith that I think it's fun
because it's very challenging.

Speaker 2 (31:55):
It challenges the creativity in my brain because
it's like okay, well, we havethis code, how do we support it?
To me, that feels like a verycreative endeavor, because it's
like you're forced to think indifferent ways.
How do you solve this problem?
So that's why I particularlyenjoy this type of work.

(32:15):
How do you?

Speaker 1 (32:17):
balance the work that you do for your day job at your
mom and pop shop shopify, asyou love to say every time.
I've heard you say that about10,000 times, but every time you
say I work at a mom and popshop Shopify, I'm just like I
forgot to say this in my intro.

Speaker 2 (32:32):
Yes, I work at a mom and pop startup called Shopify.

Speaker 1 (32:35):
Yes, I don't know why .
It just makes me laugh everytime, the same way that I laugh
when my teenager groans at mydad jokes.
It makes me feel good on theinside.
How do you balance that work?
You just talked about twopretty intense things.
At the end of the day, I feellike your brain's going to need

(32:57):
a rest.
Maybe not because you're AaronPatterson, because you're also
on the Rails core team, so youalso do Rails work At your level
.
Is that work part of your job,or is that completely separate
and that is just your hobby?
Labor of love why not?
It's?

Speaker 2 (33:15):
also part of my job.
I'm on the security team and wehave to do security crap.
Most of my recent work on Railshas mostly been security stuff,
which I hate, by the way.
It's terrible.
If anybody invites you to be ona security team, just say no,
Absolutely do not do it.
This is my pro tip for youDon't do it, it's terrible.

(33:37):
So that's most of the work andwe do that.
It's part of my job.
I guess I do that during my dayjob.
So also what I'm trying to dois at work.
We have, I described, two teamsJIT team and Ractor team, but
we actually have more teams thanthat.

Speaker 1 (33:58):
I was going to say, yeah, you gotta have a team for
everything.

Speaker 2 (34:03):
Really, there's more teams than just the two.
Shocking I work at a mom andpop shop, but we do have more
than two teams, that's true, anda handful of developers yes, a
few, a few.
These two teams are on what wecall the Ruby infrastructure
team and we also have a Railsinfrastructure team, which I am
not on the Rails infrastructureteam.
I'm on the Ruby one, but wehave a lot of folks working on

(34:24):
Rails stuff and on the Railsside of the house and I feel
like a lot of my time isespecially working with Rails.
It isn't necessarily me doingit directly, but working with
the other folks on that team totry and level them up, get them
contributing and more working onthe Rails team.
So I see myself as trying tomultiply my effort, more

(34:49):
managerial.
I suppose I start thinkingabout this.
I'm like I almost said a curseword I'm, you can curse, I curse
.
There's so many episodes I'mlike I checked the box explicit
content yeah, okay, yeah, yeah,I can't not curse I feel like
I'm turning into kind of like amanager or whatever, but it's
really just like I want to getmore folks leveled up so that we
have more contributors cominginto the rails team and working

(35:12):
on rails itself.
I don't know if this is commonfor developers or just people in
general.
So I was writing rails apps andI was like, how does rails work
?
That's how I started likeworking in rails and
contributing to rails and then Iwas like, okay, this is
interesting.
Well, how does ruby work?
And then I started going intothat and I'm like, okay, and

(35:33):
then like, keep going deeper anddeeper, and that's.
I don't know if it's a blessingor a curse, but I feel like if
my case is common, if that pathis common, then we need to get
more people into rails so theycan keep funneling down Right,
sure, fall further and furtherdown the rabbit hole.
Yeah, exactly.

Speaker 1 (35:51):
Okay, exactly, I guess that would make you the
right person to ask.
At the last RailsConf, ufuk hadpeople stand up at the various
levels of contributions to Rails.
Yeah, when we got to like, hey,if you have a commit in Rails.
Like when we got to like, hey,if you have a commit in Rails,

(36:13):
stand up.
I don't know how surprised Iwas, because there was also a
lot of first time to RailsConffolks there, but there were
people that I recognized stillsitting, which was somewhat
surprising.
How do you recommend someoneget into contributing to Rails
Rather than my first one was?
I had a problem at work.
We solved it.
I felt like it should be inRails Great, that's a pretty
straightforward.
But if someone's just sittingthere going I want to work on

(36:35):
Rails, I just don't know how.
Yeah, how would you suggestthey kind of go about getting
themselves into that world?

Speaker 2 (36:43):
Basically, I suggest the same way I did, which was
just start reading the sourcecode.
Many times I recommend peopleoh go, take a look at the docs,
you can contribute to thedocumentation.
But I have to admit, like Idon't do that, I don't document
my code.
Are you kidding?

Speaker 1 (36:59):
okay, but to be fair, it is super important.
Good documentation is crazyimportant and, like, no one
wants to do it.
That's why it's important,right?
If everyone is documenting, itwouldn't be a problem, it
wouldn't be that important.
But because no one wants to doit.

Speaker 2 (37:13):
I don't know, man.
This is what cloud is for thesedays.
I'm like tell me what thisfunction does.
I'm too lazy man.
Just like do it for me.

Speaker 1 (37:19):
Do it for me the amount that I use.
I've used AI sparingly becauseI feel like at least 40% of the
time I ask AI a question, it'swrong, and I've only caught it
because I know what I'm asking.
I'm just asking it to give me adifferent point of view and it

(37:43):
spits out some shit and I'm like, no, that's completely wrong.
And I'm like, oh shit, ifpeople start using AI without
knowing, it's going to get crazy.
I think documentation is stillcrazy important and also, what
else are we going to train theAI on?
Of course, if we don't put realhuman work into stuff, the AI

(38:05):
is not going to get trained.
I was just this morning.

Speaker 2 (38:08):
Maybe we'll talk about this a little bit later,
but just this morning I wasusing AI.
I was like, okay, if I have ameasurement in Lux and I know an
ISO, an aperture, can Icalculate a shutter speed?
It's like, oh, absolutely youcan.
It spits out a bunch offormulas.
I'm like, okay, that's veryinteresting.
Then I start doing the math.
I'm like math literally doesn'tlike it.

(38:31):
Your math doesn't math.
Yes.
I was like, okay, can you pluga few numbers in there and give
me an output for it?
So it does that.
And it's like, oh, these, thesenumbers don't seem right.

Speaker 1 (38:42):
I'm like great job but I'm like congrats job,
Congrats AI.
It's called learning.

Speaker 2 (38:48):
It's as if I asked a sixth grader to do this.

Speaker 1 (38:54):
Dude, that is actually a great description.
I have nephews who are likefour, five and six, and the
confidence they have when theyare giving me the wrong answer
to something is exactly how AItalks to me it's more endearing
when it's a child, though.

Speaker 2 (39:13):
Sure, they're cuter, yes, so back to contributing to
Rails.
What I like to do, or what Irecommend to people who don't
want to write documentation, is,though please write
documentation.
We need it, Please, please, yes, of course, course, so
important.
Start reading the source code,so in your application you know

(39:34):
you're using rails or whatever.
Pick a method that you didn'timplement, something that's
implemented in rails, and goread it and see how it's
implemented, and unfortunately,this is like a steep learning
curve.
But once you start doing that,you'll kind of get an idea of
the architecture of theinternals, and then, once you
can get an idea of thearchitecture, you can fitting

(39:55):
into your brain.
It's like, oh okay, well, I seea way, here's a way we can
improve this architecture, andthat really drives ways to
refactor or improve theinternals.
I don't know it's high effort,but just read a lot.

Speaker 1 (40:09):
I suppose I feel like that was a big turning point or
a big level up for my career iswhen I got really comfortable
reading the Rails source code,not getting afraid to be like I
don't know what this is doing, Idon't know what the various
options are.
Opening up Rails code andlooking at the method and
looking at everything thathappens under the hood.

(40:30):
I got a lot more confident inmy day job.
Now I'm reading more code but alot more confident with Rails.
Was able to make a couple ofcommits to it because of that.
So agreed, not just from a hey,I want to commit to Rails, but
like just to level up your dayjob, Knowing how the stuff
you're using works is a huge,huge thing.

(40:53):
Sure, I'll agree with that one.
So the next question on ourguardrails question is blockers,
and you sort of talked a littlebit about things that are
blocking especially with therack.
We're only at number two.
Okay, yeah, yeah, no.
Number two.
Okay, yeah, no that's great.
I'm you.
Tell me when you have to go.
I am here for you.

(41:13):
Yeah, sorry, we're only onquestion two.
You did sort of answer a littlebit with the Ractor stuff.
Blockers for Aaron Patterson.
What do they look like?

Speaker 2 (41:25):
Blockers.
I think this is funny.
We're doing stand-up questions,but we're both sitting down.
I'm standing, are you?
Oh, okay, well, I'm not Foryour listeners out there.
I am sitting down for thestand-up meeting.

Speaker 1 (41:37):
Yeah, I modeled it after stand-up, just because I'm
like people are generally usedto like what are you working on?
What blockers do you have?
Cool, it's a stand-up Blockers.

Speaker 2 (41:47):
Blockers.
My job is to solve blockers.

Speaker 1 (41:52):
That's a fun job.
What's a recent blocker thatsomeone came to you, say from
the Rails infrastructure team,and you were able to get them
unblocked.
What does that portion of yourjob look like, unblocking people
?

Speaker 2 (42:06):
One thing that I'm actively working on at the
moment.
I don't know if you sawHartley's talk at RailsConf, but
it's very good.
I recommend it.
Go look up his talk.
I'm sure it'll be in the shownotes.
Yeah, I'll put it in the shownotes.

Speaker 1 (42:23):
I'm committing to your show notes.
There you go.
Yeah, I'll put it in the shownotes.
I unfortunately did not make itto a lot of talks at RailsConf
just because I was doing programcommittee stuff and running
around like a headless chicken.
But they're all up on YouTubenow, so I'm slowly but surely
working through them.
Step one was re-watching Aji'skeynote and then watching
Marco's.

(42:44):
So good.

Speaker 2 (42:45):
So good, so good, yeah, so good, so good, yeah.
So Hartley gave a talk aboutdifferent improvements to Action
View and he was like, oh, Ihave these ideas and we should
do this and this and this.
And I watched his talk and Iwas like, yes, we should
absolutely do that, you're right.
So I'm trying to work with himon how to get him unblocked on

(43:08):
implementing these things.
So John Hawthorne implemented apre-compiler for ERB templates
and Hartley in his talk was likewe need to upstream this and
this should come with Rails bydefault.
And I was like, yes, it shouldplease make it.

Speaker 1 (43:27):
So the wonderful thing about open source if you
want it make it, so Make it so.

Speaker 2 (43:36):
So I am blessed that he is on the Rails
infrastructure team so I canping him on Slack, and I was
like I like your idea.
What do we need to do?
So he's starting to work onthat.
The first thing is for templatecaching, like.
Another thing he was talkingabout in his talk was template
caching.
So we have to detect calls torender in ERBs in order to like

(43:56):
figure out what the cache keysare.
And we're doing that withbasically a pile of regexes,
which, as we all know, is likethe best way to solve every
problem.
Sure, Just slap another regexon there, you're good to go.
Actually, no one needs to readthis shit later.
No, and you know what?
I recently read a blog postabout how you're supposed to add

(44:18):
slash O to all of your regexes,because it just makes them
faster.

Speaker 1 (44:22):
Yeah, that's exactly what that blog post.
I'll include that blog post inthe show notes too.
This is going to be very longshow notes just all your
listeners out there.

Speaker 2 (44:33):
Just put that O on the end.

Speaker 1 (44:36):
Slash O at the end it'll be.

Speaker 2 (44:37):
Everything's faster, so it's all better.
But yeah, so he was talkingabout how to detect these render
calls in a more robust way thana pilot reg access, and that's
by using a actual ruby parser.
So the first step was gettingthis ruby parser integration in

(44:59):
and on by default, and I mergedhis pr to do that.
So in Rails 8.1, we'll be usingPrism for detecting render
calls for your template cachekeys.
I asked to keep the pile ofregexes around.
It's a configurable option, soif you happen to run into any
problems, you can like downgradeif you need to, but hopefully

(45:22):
there won't be any problems andthen we'll just delete the
regex-based one later.
So those are the things we'reworking on.

Speaker 1 (45:29):
Is the work that Marco's doing on Herb and ERB on
your radar?
Yes, I hear parallels right now.

Speaker 2 (45:38):
Yeah, yeah, yeah, marco's work is awesome.
Love, love his work.

Speaker 1 (45:43):
Yes, is that one of those?
As you're working with some ofthis Action View stuff, you're
considering the things that he'sdoing and seeing.
Maybe this can get plucked andbrought in, or we can make
Marker's life easier by doing X.
Or how does coordination withthe community work at a Rails
core team level?

Speaker 2 (46:02):
Sure, I have to admit I didn't think about it until
just now.
Okay, cool, well, there you go.
So I've seen his work and I'm ahuge fan of any way we can get
language servers and stuff thattype of stuff.
So I guess, for folks thataren't familiar with his work,
he's doing a lot of work on thelanguage server and editor
integration.

(46:22):
Specifically, If I remembercorrectly, the talk you gave at
RailsConf was about Curb H-E-R-B, which is a language server for
ERB, so making ERB better.

Speaker 1 (46:36):
It's a tool chain.
Essentially it's multiplethings.
It's the LSP, the parser forERB and HTML.
If you're not familiar withwhat we're talking about right
now, go listen to the episodethat came out right before this
one, which would actually beMarco talking about some of that
work.
We'll have a link to it in theshow now.

Speaker 2 (46:56):
We'll have a link to it in the show yes.
I hadn't thought about that.
We should, because I'm a hugefan of his work and I think that
type of stuff should just shipwith rails out of the box.
I'm not sure what that lookslike.
Booting an lsp server inaddition to your rail server is

(47:18):
like heavy lift, I think mainlybecause I don't think we want to
maintain that type ofcomplexity, because that's a lot
of stuff.

Speaker 1 (47:29):
Yeah, he has a long list of like.
This is what I'd like to getout of Herb.
Here's some tools that we canbuild, because now we have a
good parser for HTML with ERB,we have a linter, we have a
formatter, we have all thesethings that build on top of one
another and then, oh hey, alsokind of compiling erb is a
little slow because we're doingit this way.

(47:49):
We can do it another way now,and potentially this should be
part of rails, where we treatour erb views a little bit more
like code because sort of whatthey are.
But yeah, I mean, he's got alot of interesting ideas and
there was a lot of parallels inwhat you had just said.
So I didn't know if, obviously,it's not on your radar, wasn't

(48:09):
on?
Your radar Sounds like it isnow.
But from a being on the Railscore team perspective, how does
that kind of community I don'tknow if it's engagement or
coordination or what have youhow does the Rails core team
keep tabs on what the communityis doing and things like that?
So how do?

Speaker 2 (48:30):
we keep tabs.
The short answer is we don't.

Speaker 1 (48:37):
It's on the people building things, to kind of
bring it to the core team'sattention.

Speaker 2 (48:41):
Yeah, yes, yes.
Longer answer is the way thatwe work on the core team is very
independent.
There's basically zerocoordination among the folks on
the core team.
So, like I go to conferencesand watch talks, that's how I
know about these things orthings that the team brings to
me, but we don't make any sortof coordinated, concerted effort

(49:02):
to know about these things.
So the best way, if you have athing you think should be in
Rails, best thing for you to dowould be to file a pull request
or something like that, or, Idon't know, speak to one of us
directly, like email me oractually don't email me.

Speaker 1 (49:24):
Don't email you if you are expecting a response or
your wife might respond that's afact?
Yes, for sure.
So the last question is myfavorite.
So what is something cool, newor interesting that you've
recently learned, discovered,built or building?
Anything doesn't have to becoding related, but this is code
and the code encoders who codeit.
So what do you got I'm?

Speaker 2 (49:46):
working on another hardware project.
It's not an analog terminal,but this is code and the code
encoders who code it.

Speaker 1 (49:50):
So what do you got?
I'm working on another hardwareproject.

Speaker 2 (49:51):
It's not an analog terminal bell.
No, it's not an analog terminalbell.
That'll be in the show notestoo.
I love promising things.
It'll be in your show notes.
This is great.
So during the pandemic I'm goingto give a little bit of history
here.
During the pandemic, I bought acamera because I was like I'm
going to be doing a lot ofmeetings at home.
I would like to have a highquality camera with which to

(50:14):
show my face across the Internet.
So I bought a camera and then Iwas like I should probably
learn how to use this as aregular camera.
So that's what I did and itturned into a hobby hobby which
is very expensive hobby.
If anybody is into this hobby,you will know it's quite
expensive.
And one thing I learned aboutis that, as a programmer, the

(50:38):
problem with any hobby is like Isomehow turn it into
programming.
Of course, yeah, because that'slike my actual interest here.
Apparently, I shoot my photosall in raw.
To be more explicit, I dophotography as a hobby.
I shoot all my photos in raw,and what that is when you shoot
a photo in raw, you're gettingthe data directly from the
camera's sensor, whatever thesensor recorded.

(51:00):
That's what you get and that'sgreat and fine.
But the problem is sensors aredifferent.
Each sensor is different.
I have an olympus camera.
Even if you buy two olympuscameras, like the data it's not
going to be exactly the same.
So they calibrate these thingsat the factories and the

(51:20):
calibration is all done insoftware.
So if you shoot in raw, thatcalibration stuff doesn't apply
to the RAW file at all becauseyou're getting truly the data
that just came from the sensor.
So, like when your camerarecords red or whatever it's not
truly that color you have tohave this calibration applied to
it.
The calibration gets applied toit if you also record the image

(51:42):
as JPEG.
So the JPEG version gets thecalibration stuff applied to it,
but it also gets other likewhatever they want to do to the
jpeg.
So of course, me, being the nerdthat I am, I'm like okay, well,
I need this calibration data.
I want this calibration databecause then I can apply that to

(52:04):
the raw photos, like when Itake them out of.
Because then I can apply thatto the raw photos, like when I
take them out of the camera.
I can apply that calibrationdata and get better colors.
It's true, you absolutely doget better colors.
So what you do is they havethese color tester things.
It's like a thing with a gridof colors on it, but the colors
are known in advance.
You take a photo of that andthen in software you lay a thing

(52:26):
over it and you're like pleasefit this to these particular
colors and since the colors areknown in advance, you can come
up with the right coefficientsto apply.
Now I know it's a long yakshave, but here we go.
So when they do thesecalibrations at the factory,
they have these color charts,but you have to shine a

(52:48):
particular color of light on it.

Speaker 1 (52:51):
Okay, that makes sense.

Speaker 2 (52:52):
So, like think about, during the day, like in the
evening, the sun is very orangeand the light that shines from
is very orange, versus duringthe day, it's quite white.
Our eyes perceive whitedifferently.
Like we'll look at white, it'snot actually white.
You'll notice if you've evermucked with the white balance on
your camera.
It's like oh, why does thislook all weird?
In my camera I see white.

(53:13):
Why is it blue on here?
But they record it at what theycall d50, which is 55 000
kelvin, like temperature colortemperature yeah yeah.
So if you want to reproduce whatthey do at the factory, you
need one of these color checkers.
Plus you need a 5000 kelvinlight source.
So I'm like, okay, well, how doI get 5000 kelvin light source?

(53:38):
Maybe you can buy a light thatproduces 5000 kelvin light.
But then it's like are you surethat that's the color that's
reaching?
Is that actually the colorthat's at the color checker?
Are we sure?
Are we sure?
So I'm building a colortemperature sensor.
Of course you are.
Yes, that's my current projectat the moment.

(54:00):
I've already spent way too muchon this project.

Speaker 1 (54:04):
Time or money or both .
I've already spent way too muchon this project.
Time or money, or both Both.

Speaker 2 (54:07):
I've already bought so far three color temperature
sensors, so you can just buy acolor temperature sensor.
If you try to buy a commercialone or whatever, like a built
product, they're very expensive.
So even though I've alreadysunk time and money into this,
I'm still saving money.
Because your time is useless.

Speaker 1 (54:24):
Exactly, I don't value my time't value.

Speaker 2 (54:25):
I don't value my time ?
I absolutely don't value mytime.
So that's free, that's all free.
We only got the cost of partshere, which is really nice.
I've already bought threesensors and, interestingly, like
the first two sensors sucked.
It was just like bad, and Ihate going through data sheets,

(54:46):
it's so like just annoying.
And it turns out that the firsttwo sensors I bought you have to
calibrate it.
So basically, you get somereadings out of the sensor, you
get basically RGB values they'rejust like some number and then
you have to convert those intowhat they call the CIE spectrum,
which is some more nerd shit.

(55:07):
And then you take that and youcan convert that into the color
temperature.
What we're looking for, thething that we're actually trying
to get to, but the coefficientsthat you need to apply to each
of these RGB values changesdepending on the sensor that
you're using, and what sucks isyou have to calibrate it in
order to find those coefficients.

(55:28):
That's the whole point here.
I'm trying to build acalibration that I don't want to
calibrate shit.
I'm building a calibrationthing.
I don't want to do more.
Don't make me do more.
So the third one I found it'sself-calibrating.
I'm like, ah, okay, that's whatwe need, so I finally found a
sensor like that.
I got that going.
I'm going to build a colortemperature meter so that I can

(55:51):
calibrate my camera and then,finally, I'll be able to take
photos.

Speaker 1 (55:59):
It's a lot of work to take a photo.

Speaker 2 (56:01):
I know right, you can't just point that thing and
click the button.

Speaker 1 (56:04):
It's amateur hour, yeah, come on, come on.

Speaker 2 (56:07):
We got to put more work into this.

Speaker 1 (56:09):
Way more work.

Speaker 2 (56:10):
Yes, like I was saying to you earlier,
unfortunately this project, asopposed to my other projects,
might be useful, which is a badthing.
I need to come up with a moreuseless project.
The thing that sucks about thisis I'm going to calibrate the
camera once and that's all youneed.
That's so much worse.

(56:36):
Oh my god, just once, but it'sstill cool.
It's like whoa.
I think all of us, all of ushave wondered what temperature
is this light?
We're all wondering thatconstantly, all the time, all
the time.
Yes, you just want to know.
You're like boy.
This seems like a cool light.
I bet this is like I don't know3200 kelvin.

Speaker 1 (56:51):
I'm not even sure if that's the right one I don't
remember if the value goes up ordown for the temperature?

Speaker 2 (56:58):
I have no idea.
I'm so bad at this.
I'd have no idea.
I don't know.
But yeah, we're building a tool, exactly.
Yes, I'm building a tool forthis.
I don't need to know this.
You build a tool for this.
It's like I don't rememberanything.
I don't think or rememberanything at all.
That's why I always read thesource code.
It's like well it's, I can justgo read the code.
Why do I need to?

Speaker 1 (57:18):
remember shit, a little bit of just-in-time
knowledge, right yes, yes,absolutely.
I mean, remembering stuff isfor losers man I mean humans
invented writing for a reasonexactly we didn't have to
remember, we don't have toremember stuff.

Speaker 2 (57:31):
Yes, that's why I got a calendar.
I love the calendar.

Speaker 1 (57:34):
If it's not in the calendar, it doesn't exist, not
gonna work sometimes, if it's inthe calendar, it still doesn't
exist, to my brain at least yes,indeed, indeed yes.

Speaker 2 (57:45):
That's a project I'm working on at the moment.
I'm having a really, reallygreat time.
I don't know, it's a lot of fun, because it's like oh, I took a
photography hobby.
How do I get programminginvolved in this?
I don't mean to get programminginvolved in it's, just that
this happens well when all yougot's a hammer.
You know what I'm saying, sure,yep yeah, everything, every

(58:12):
single thing.

Speaker 1 (58:13):
That happens in programming too, where you're
like I found this cool thing youcan do in Rails and suddenly
every place can get solved bythis unknown, obscure Rails
concept that's why all of mywebsites, just web soets all the
time, just only WebSockets.

Speaker 2 (58:28):
That's all it is, that's all you need.
Yeah, don't need live updates,I don't even care, but still
WebSocket.

Speaker 1 (58:34):
Yeah, what is HTTP anyway?

Speaker 2 (58:36):
We got.

Speaker 1 (58:36):
WebSockets?
No idea, amazing.
Okay, so out of respect foryour time, we'll wrap this shit
up.
But Out of respect for yourtime, we'll wrap this shit up,
but this was awesome.
I was very nervous going intothis podcast recording, which I
never get nervous for podcastrecordings anymore.
I used to get very nervous.
I still get a little nervousbecause I'm like I want this to
be good and I want the otherperson to have a good time.

(58:58):
But this is.

Speaker 2 (59:00):
I was talking to Aaron Patterson, who I guilted
hard into coming on my show.

Speaker 1 (59:07):
I have to make it good.
This is great.
I have to say out loud thankyou for everything that you're
doing for Ruby, for Rails, havedone for us, and for the
countless hilarious keynotesthat just have been the best
part of every RailsConf I'veever gotten to.
Thank, you.

Speaker 2 (59:28):
I really, really appreciate that.
It's very kind of you.

Speaker 1 (59:30):
And thank you for coming on the show, setting time
out of your day to just talkabout all the cool things.
Anytime you're working onsomething and you just want to
talk about it, feel free to comeback on Love to have you.
Sure, the format doesn't change, it's.
What are you working on?
What blockers do you have?
What's something cool?
You got going on and you alwaysseem to have something cool

(59:51):
going on.

Speaker 2 (59:52):
We never have the what's cool going on at our
standups.
I got to integrate that.

Speaker 1 (59:56):
Sounds like you need to integrate that.
Yeah, bring that back toShopify and get them working on
that, and then let me know ifyou do, and I'll include that in
the show notes too.
Nice.
So, aaron, for those who don'tknow, where can people find you
on the internet?

Speaker 2 (01:00:12):
You can find me on bluesky at tenderlovedev or you
can email me.
It's aaronpatterson at gmailcom.
Oh, and then I got to plug myYouTube channel.
What am I?

Speaker 1 (01:00:23):
doing?
Oh yeah, of course, yeah.

Speaker 2 (01:00:27):
I'm so bad at this.
It's Tenderlovescoolstuff onYouTube.
Yes, come watch me live streamonce in a while.
I keep a strict schedule.

Speaker 1 (01:00:35):
Of occasionally Of occasionally, yes, but always
great content and great guestson that one too.

Speaker 2 (01:00:41):
So I will include all of that in the show notes, all
the show notes you don't evenneed to listen to this episode,
just read the show notes andclick all the links.

Speaker 1 (01:00:53):
But hopefully you did listen to this episode and you
enjoyed it and we will see you,or I will see you, at least, or
I'll be in the next one.
Aaron won't be, I will be.
I don't know how to end apodcast.
Can you tell, okay, listeners,I will be.
But yeah, I don't know how toend a podcast.
Can you tell, okay, listeners,I'll see you in the next one.
Bye.
Advertise With Us

Popular Podcasts

Las Culturistas with Matt Rogers and Bowen Yang

Las Culturistas with Matt Rogers and Bowen Yang

Ding dong! Join your culture consultants, Matt Rogers and Bowen Yang, on an unforgettable journey into the beating heart of CULTURE. Alongside sizzling special guests, they GET INTO the hottest pop-culture moments of the day and the formative cultural experiences that turned them into Culturistas. Produced by the Big Money Players Network and iHeartRadio.

Dateline NBC

Dateline NBC

Current and classic episodes, featuring compelling true-crime mysteries, powerful documentaries and in-depth investigations. Follow now to get the latest episodes of Dateline NBC completely free, or subscribe to Dateline Premium for ad-free listening and exclusive bonus content: DatelinePremium.com

The Charlie Kirk Show

The Charlie Kirk Show

Charlie is America's hardest working grassroots activist who has your inside scoop on the biggest news of the day and what's really going on behind the headlines. The founder of Turning Point USA and one of social media's most engaged personalities, Charlie is on the front lines of America’s culture war, mobilizing hundreds of thousands of students on over 3,500 college and high school campuses across the country, bringing you your daily dose of clarity in a sea of chaos all from his signature no-holds-barred, unapologetically conservative, freedom-loving point of view. You can also watch Charlie Kirk on Salem News Channel

Music, radio and podcasts, all free. Listen online or download the iHeart App.

Connect

© 2025 iHeartMedia, Inc.