Charles Max_Wood:
Hey, welcome back to another episode of RubyRogues. This week on our panel we have Valentino Stoll.
Valentino_Stoll:
Hey there.
Charles Max_Wood:
I'm Charles Maxwood from Top End Devs. It's just the two of us this week. We're gonna be talking about Ruby 3.2.
Valentino_Stoll:
Yeah, lots of good stuff coming out.
Charles Max_Wood:
Yeah, I'm a little curious before we get too far into things. Have you played with it much or?
Valentino_Stoll:
Yeah, I've been experimenting mostly because they have all the dev tooling kind of introducing now, which is really fun to work with.
Charles Max_Wood:
Right. Very cool. Yeah, I've kind of looked at it, but I've been pretty buried with other stuff and I haven't been able to play with it and see what happens. So yeah, let's jump in and talk through some of this stuff. By the way, I'm getting a little bit of echo on your end, so I'm gonna turn on echo cancellation or something. Oh, I can't turn it on while we're recording. Okay, we'll do the best we can. So yeah, so where do you wanna start? I mean, there's so much in here. Like you said, a lot of dev tooling. There's some performance stuff. I see some like WASM stuff. Yeah.
Valentino_Stoll:
Yeah, I mean, we could dig into the performance first. I mean, that's definitely hands down
Charles Max_Wood:
Yeah.
Valentino_Stoll:
the largest improvements.
Charles Max_Wood:
Yep, I mean I'm seeing something here about YJIT and I think we did an episode on that a while back.
Valentino_Stoll:
Yeah,
Charles Max_Wood:
Do
Valentino_Stoll:
it's
Charles Max_Wood:
you feel
Valentino_Stoll:
kind of
Charles Max_Wood:
it?
Valentino_Stoll:
like a cult. We've had Kevin Newton on quite a few times
Charles Max_Wood:
Uh-huh.
Valentino_Stoll:
who's been working on not only YJIT, but a lot of the parser stuff.
Charles Max_Wood:
Right.
Valentino_Stoll:
And we've had, is it? I'm forgetting his name now. gonna have to find this or it's gonna drive me crazy.
Charles Max_Wood:
Yeah, uh, Takashi?
Valentino_Stoll:
Takashi. Yep.
Charles Max_Wood:
Takashi Cocoboon? Yeah.
Valentino_Stoll:
And he's also on the Wydja team. And
Charles Max_Wood:
Yeah.
Valentino_Stoll:
I mean, it's just kind of incredible to see the numbers. So
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
I was taking a look at a couple benchmarks that are out there. You can view these for yourself. Shopify is pretty open about what they're benchmarking against. And you know, Railsbench being one of them.
Charles Max_Wood:
Right.
Valentino_Stoll:
Also against Active Record liquid template rendering. I just like kind of across the board just using YJIT, you know, they see like north of 30% performance increase just using YJIT.
Charles Max_Wood:
Nice. Yeah, it's always interesting because we talked to Takashi before it was released and it's interesting to see, okay, where's it at now? But what does it really look like when they go, oh, here.
Valentino_Stoll:
Great.
Charles Max_Wood:
Here's a production version.
Valentino_Stoll:
Yeah, I mean, if you just focus on active record, which, you know, most people
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
will probably see the best improvement from, you know, that's at 37% from their benchmarks. And so just
Charles Max_Wood:
Nice.
Valentino_Stoll:
just using Ruby 3.2, you get that out of the bag with your Rails app. It's kind of incredible.
Charles Max_Wood:
Yep.
Valentino_Stoll:
But you know, it's been combined with a few other things kind of on their memory side.
Charles Max_Wood:
right.
Valentino_Stoll:
Ruby's memory footprint is notoriously a hog.
Charles Max_Wood:
Uh, yeah, it's, it's better than it was when I started writing Ruby,
Valentino_Stoll:
For
Charles Max_Wood:
what,
Valentino_Stoll:
sure.
Charles Max_Wood:
16 years ago, but it's, yeah, it's, it's still not ideal.
Valentino_Stoll:
Yeah, so I mean, the two topics I see that come out of 3.2 are the variable with allocation and object shapes.
Charles Max_Wood:
Uh huh.
Valentino_Stoll:
And variable with allocation is pretty neat, kind of just a way of minimizing how objects grow.
Charles Max_Wood:
Right.
Valentino_Stoll:
So like if an array starts at no objects, it has a certain way of expanding the memory footprint the objects you put in that kind of thing. It's kind of over my head, but I'm happy to see that memory allocation is being worked on
Charles Max_Wood:
Right.
Valentino_Stoll:
because I don't like to think about it. I don't know about you.
Charles Max_Wood:
No, I agree. This kind of makes me want to upgrade my stack just to be able to use this, right? Because I mean, I don't know if I would necessarily downgrade any of the servers or systems that I'm using, but I mean, it gets me more mileage out of the stuff I've already got out there, right?
Valentino_Stoll:
Oh yeah, for sure. I mean, I use a Hogan server, which is built on Ruby. Yeah,
Charles Max_Wood:
Huggin? Huggins?
Valentino_Stoll:
it's basically a if then this, that, but all locally stored and you run it yourself kind of thing.
Charles Max_Wood:
Oh,
Valentino_Stoll:
It's
Charles Max_Wood:
interesting.
Valentino_Stoll:
super, super fun to play with. And I hook up a lot of automation to my home assistant through that.
Charles Max_Wood:
Here we go, hug in.
Valentino_Stoll:
and didn't have any issues really just using a different, you know, Ruby 3.2 Docker container.
Charles Max_Wood:
Right. I never even thought to look for a if this then that replacement.
Valentino_Stoll:
Hahaha
Charles Max_Wood:
You might have just changed my whole outlook on things.
Valentino_Stoll:
Yeah, I mean, we could probably do a whole episode just on hugging.
Charles Max_Wood:
Well, yeah, we may just want to get whoever built it on and just say, hey, what is this? And what did you learn putting it together?
Valentino_Stoll:
Yeah, it's super cool. Pretty well built. I mean, I haven't had any issue on it. It's like, kind of takes a bit to get your head around how all the different services come together. Cause it's like, you know, I wouldn't say microservice architected, but the concepts are.
Charles Max_Wood:
Right?
Valentino_Stoll:
Cause you just have a bunch of, you know, services that you want to listen and emit events, and then things receive events, do other things with them. But once you get past that, the front end interface has a whole web UI and it's really not that hard to get going on it.
Charles Max_Wood:
Right.
Valentino_Stoll:
It's a lot of fun.
Charles Max_Wood:
Huh. Yeah, I'm going to have to play with it and see what I can do with it, because I'm really curious to see how that comes together. And we'll put a link to it in the show notes. It's H-U-G-I-N-N. But yeah, because I pay for Zapier, and I've paid for make.com is the other one that I use. And
Valentino_Stoll:
Yeah.
Charles Max_Wood:
I mean, it's nice to not have to write those integrations, right? Figure out, OK, API this, API this,
Valentino_Stoll:
Right.
Charles Max_Wood:
Okay, now I've got to glue it together.
Valentino_Stoll:
Yep.
Charles Max_Wood:
But yeah, I'd be really curious to see how this goes. And mostly is to automate the processes around the podcast.
Valentino_Stoll:
Oh cool,
Charles Max_Wood:
Anyway,
Valentino_Stoll:
yeah.
Charles Max_Wood:
so are you seeing, you said you moved it up to 3.2. Were you measuring any of the performance before or after?
Valentino_Stoll:
Well, so I had it on a free Heroku instance, which
Charles Max_Wood:
Uh huh.
Valentino_Stoll:
is no longer free. But
Charles Max_Wood:
Ha ha
Valentino_Stoll:
I
Charles Max_Wood:
ha!
Valentino_Stoll:
did deploy it. I have my own Linode server that I now have a
Charles Max_Wood:
Right.
Valentino_Stoll:
Heroku clone of, Dokku. And I deployed it on that. And I did see a significant reduction in memory usage, which was kind of wild.
Charles Max_Wood:
right.
Valentino_Stoll:
But I'm not like a power user, so take that with a grain of salt.
Charles Max_Wood:
Yep.
Valentino_Stoll:
But I mean, just deploy something and see instant results. I mean, that's pretty wild.
Charles Max_Wood:
Right.
Valentino_Stoll:
All I did was
Charles Max_Wood:
Yeah.
Valentino_Stoll:
upgrade the Ruby.
Charles Max_Wood:
Yeah, doku is another thing that I need to have a deeper look at because I'm deploying to separate servers. It's kind of a pain in the butt using Capistrano and stuff. I mean, it works now, but yeah, it'd be interesting to dive into that. But yeah,
Valentino_Stoll:
Yeah, I mean,
Charles Max_Wood:
anyway.
Valentino_Stoll:
I mostly started with that because I didn't understand Docker containers at the time.
Charles Max_Wood:
Uh-huh.
Valentino_Stoll:
And I just wanted a quick way to push something up and let it just handle itself. And that was an easy way, easy out. There could be a better thing, so use what you know.
Charles Max_Wood:
Yep. Well, I'd kinda like to get deeper into the container arena and get to know it a little bit better, but. Anyway, so yeah, so I'm liking that and the YJIT, I mean, we've talked about it, so we don't have to go into too much detail, but yeah, it's just-in-time compilation. And so yeah, as your program runs, it compiles more and more of your work so that it can run it in a faster way, basically.
Valentino_Stoll:
Yeah, I mean, we'll see. I'll keep benchmarking my own and see if it improves over time, right, which is kind of the whole thing. The longer that it's running,
Charles Max_Wood:
Yep.
Valentino_Stoll:
the better it should get. But
Charles Max_Wood:
Yep, absolutely.
Valentino_Stoll:
so far so good. I mean, first impression's pretty great.
Charles Max_Wood:
Yep, I'm looking through the changes that they listed. I don't know if I see the object shape or whatever you were talking about there.
Valentino_Stoll:
Yeah, so
Charles Max_Wood:
Oh, here we go.
Valentino_Stoll:
object shapes are really cool, kind of started by the late Chris Seton. And I know Gemma Isroff is kind of also taking over a lot of that.
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
And it's just kind of wild adding metadata to the objects, the Ruby objects themselves, what objects contain what data and reference to who their hierarchy is and things like that. And by adding that metadata, Ruby can search through those dependency graphs much quicker.
Charles Max_Wood:
Oh, I see. So then it allows it to go in and clean it up more efficiently.
Valentino_Stoll:
Yeah, and they're able to target what constants they need to pull from during runtime and what instance variables are declared on it and things like that. So just having that metadata on top of every object, just like it gives so much opportunity there to help optimize the Ruby runtime as it goes, because it doesn't have to figure out what those things are. memory after the fact. So it'll be interesting to
Charles Max_Wood:
Yep.
Valentino_Stoll:
see how that develops. It's kind of still a little early I think, but pretty cool stuff.
Charles Max_Wood:
Yeah,
Valentino_Stoll:
But I would
Charles Max_Wood:
I'd
Valentino_Stoll:
say...
Charles Max_Wood:
love to see where we go with it. Yeah.
Valentino_Stoll:
The most excited stuff I've been for Ruby 3.2, and I mean, this is probably the stuff I've had the most experience with working, is all the dev tooling. So there's like
Charles Max_Wood:
Right.
Valentino_Stoll:
a number of new tools that have surfaced from all of the extra work, from the parser and... What was it,
Charles Max_Wood:
Right.
Valentino_Stoll:
the error highlighter as an example.
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
But basically what I've discovered is the Ruby language server protocol or a Ruby LSP
Charles Max_Wood:
Yeah.
Valentino_Stoll:
gem. And it's just so incredible. It lets you run the language server and hook it up to your favorite editor and give you kind of a bunch of different actions. that you can capture. And as an example, like hovering over a constant, and you can go to definition of it, peek into how it's defined. A lot of things that maybe we're taking for granted from other languages.
Charles Max_Wood:
Right.
Valentino_Stoll:
And it's just so much fun to play
Charles Max_Wood:
So,
Valentino_Stoll:
with.
Charles Max_Wood:
yeah, now my familiarity with language services, language servers is basically down to how VS code, right, connects with my program. So is this gonna enhance my experience there? And maybe in like RubyMine and other things, you know, as those get implemented? Or how is this gonna impact me? Because I don't know that I'm gonna use these tools Right?
Valentino_Stoll:
Right. Yeah, so I mean, those are all of they're like a, you know, as an example, VS code, there's a Ruby LSV extension
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
that kind of brings that all these new features to that particular
Charles Max_Wood:
Okay.
Valentino_Stoll:
editor. It's kind of what's been targeted for, you know, a first draft of it.
Charles Max_Wood:
Right.
Valentino_Stoll:
And that's where you'll see most of the the supportive features out of it. Um... So I mean, I've seen a few others, like a Vim one as an example, because there's a Vim LSP that you can plug into and use the language server provided by Ruby now to tie into a lot of the common things, like you'd have like a hover over a word or something like that.
Charles Max_Wood:
All right.
Valentino_Stoll:
So it's a lot of fun kind of seeing what's coming out of it. Now that it's like, you know, kind of baking into the language, there'll be a lot more, you know, coming out.
Charles Max_Wood:
Right, well that's exciting.
Valentino_Stoll:
And so it'll be interesting to see how you can maybe execute Ruby from the line that you're on.
Charles Max_Wood:
Uh huh.
Valentino_Stoll:
Just the endless possibilities.
Charles Max_Wood:
Right? Yeah, that's exciting. Yeah. I mean, and some of it, it catches syntax. Some of it's the error highlighting, like you mentioned. Yeah, anyway, it's really cool if you want to go look at the documentation for what they released. Um, we mentioned performance before there's the MJIT and the YJIT. Is, do you have to do something different to use MJIT versus YJIT?
Valentino_Stoll:
Yeah, there's a special flag. And you can turn it on by default if you're running it behind some server. But if you're just running a Ruby script as a daemon or something like that, you can provide the flag to run it in a special case.
Charles Max_Wood:
Does it default to one or the other?
Valentino_Stoll:
It defaults to off still, I believe.
Charles Max_Wood:
Okay.
Valentino_Stoll:
I don't know if that switched in 3.2. I feel like it didn't.
Charles Max_Wood:
I'll have to look it up and see if I can find something that tells you how to, because what I'd like to do is if it speeds up Rails, I want to turn it on for my Rails apps.
Valentino_Stoll:
Yep.
Charles Max_Wood:
Yeah, we'll have to see what comes out of that, but that's cool stuff. Um, one other thing that caught my eye was the web assembly support.
Valentino_Stoll:
Yeah, this looks really cool. Yeah, one of the things I noticed is that they gave an example of this WASI VSF, the virtual file system layer.
Charles Max_Wood:
Uh-huh.
Valentino_Stoll:
So you can basically compile your compile Ruby as a WASM
Charles Max_Wood:
Right.
Valentino_Stoll:
file itself. So that comes packaged kind of as part of it.
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
Plasm, executables to run them.
Charles Max_Wood:
Right. And so it runs the packaged Ruby version with the program you wrote.
Valentino_Stoll:
Right.
Charles Max_Wood:
That's awesome too. I wanna go play with all this stuff.
Valentino_Stoll:
Yeah, it'll be interesting. I know that there is a JavaScript package of this that you could play with that I
Charles Max_Wood:
Uh-huh.
Valentino_Stoll:
think that they use for the Try Ruby website.
Charles Max_Wood:
Yeah, we talked to, what's his name? The guy that did Opal. Back in December we talked to him and it sounds like they're using Opal for Tri Ruby, or at least they were, until this got released. I don't know.
Valentino_Stoll:
Yeah, so I think the default is opal and
Charles Max_Wood:
Yeah.
Valentino_Stoll:
the fallback is the wasm. So
Charles Max_Wood:
Okay.
Valentino_Stoll:
you can kind of run them both through each and see how they interpret it maybe differently.
Charles Max_Wood:
Right.
Valentino_Stoll:
It's kind of fun to play with. But I mean, I would just love to just, you know, write some Ruby code and then throw a single line of JavaScript on a page in the header and just have it work, right?
Charles Max_Wood:
Right.
Valentino_Stoll:
That would be so fun. Thanks for watching!
Charles Max_Wood:
Yeah, the other thing that it talks about is a lot of the edge computing runs a JavaScript engine and a WebAssembly engine, right? And so if you have a WebAssembly engine out wherever, right, you can write JavaScript, you can write some other language that compiles to WASM, and that includes Ruby. And so...
Valentino_Stoll:
Yeah, I think ABWs Lambda even supports serverless
Charles Max_Wood:
Yeah.
Valentino_Stoll:
functions in WebAssembly. So
Charles Max_Wood:
Yep.
Valentino_Stoll:
it's just wild.
Charles Max_Wood:
Yeah. And again, you know, it's just, it opens up all these avenues for you to do what you need to do without necessarily having to write another language. I mean, I don't know if there are performance implications or other things to that, but for the most part, it's exciting just to be able to go, you know what? I can be productive in my programming with this stuff.
Valentino_Stoll:
Yeah, I mean, I guess it comes down to how heavily you're using it, right?
Charles Max_Wood:
Right.
Valentino_Stoll:
I think for just kind of fun one-off scripts, like WASM makes so much sense, right? Like
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
if you're just trying to play in something and you want to see how it, a preview of how it's running or works, like, you know, WASM is great. Like
Charles Max_Wood:
Yep.
Valentino_Stoll:
do it in whatever language you're doing and then post it up, like publish
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
and you know get it working in the browser. Everybody has a browser right?
Charles Max_Wood:
Yup. Yeah, I mean, yeah. I don't know, I mean, I'm kind of excited just to, like I said, just go see what I can do with it. Are there other use cases for that that you can think of or?
Valentino_Stoll:
Um, I'm not sure really. To be honest, my, my usage of wasm is pretty low other than just like seeing how other people have used it.
Charles Max_Wood:
Yeah, same. Yeah. Were
Valentino_Stoll:
But
Charles Max_Wood:
there,
Valentino_Stoll:
I-
Charles Max_Wood:
were there other things? Yeah, go ahead.
Valentino_Stoll:
Yeah, I was just going to say, I mean, if you have, you know, the best example I can think of is like, you know, wasmkin is really useful if you like have a problem with people that write in a bunch of different languages and you want them to just all consolidate into one thing. But I mean, that that introduces introduces its own things. Maintainability
Charles Max_Wood:
Yep.
Valentino_Stoll:
as an example, but. I don't know, back to Ruby.
Charles Max_Wood:
Hahaha
Valentino_Stoll:
One thing I did notice, back to the performance stuff, is there was a lot of work into the regular expression algorithms. And the long-term performance implications of it are just incredible.
Charles Max_Wood:
Yep.
Valentino_Stoll:
And just as an example, like some regular expressions after, you know, after say 30 times of it being captured, you know, the time it took after each successive match just climbed through the roof exponentially. And so that's kind of been normalized now. you know, it takes about the same amount of time every time to look through, you know, matches. So you just don't get lags anymore. I don't even know how that works. I would go check it out and, you know, write up an article so I could get the TLDR, but I didn't know that this was even a thing that I should be watching out
Charles Max_Wood:
Uh
Valentino_Stoll:
for.
Charles Max_Wood:
huh.
Valentino_Stoll:
And it's
Charles Max_Wood:
Right.
Valentino_Stoll:
got me going to check sure you know there aren't any cases that that may be like causing some bottlenecks.
Charles Max_Wood:
Yeah.
Valentino_Stoll:
Um. That was interesting. But playing with Ruby 3.2, I would say maybe second to the actual language server stuff was
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
this error highlight
Charles Max_Wood:
Yeah.
Valentino_Stoll:
written by Yusuke Yando. And it's just so much better. I don't know if you've ever gotten one of the undefined method for nil class errors
Charles Max_Wood:
Oh yeah, all the time.
Valentino_Stoll:
But now
Charles Max_Wood:
It's fun.
Valentino_Stoll:
it tells you right, you know, and it highlights, you
Charles Max_Wood:
Yeah.
Valentino_Stoll:
know, kind of with the exact place that, you know, it happens. So you could see it, you know, it's
Charles Max_Wood:
Yep.
Valentino_Stoll:
the how this was missing for so long, you know.
Charles Max_Wood:
Well, it's funny because... I either joke about or talk to people, and pretty much everybody agrees that 95% of the errors you get are, this method doesn't exist on nil, or something related to that. This one is nil can't be coerced on the webpage. And so, yeah, then it's, okay, well, I've got nine variables on that line. Which one's nil? And yeah, I mean, that clears it up. It's like, hey, this guy right here can't, you know, I didn't expect it to be nil.
Valentino_Stoll:
Great. Yeah, I mean, kind of kind of in line with that thinking is the new data object.
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
Which kind of goes to as a stand in for for struct. Because if you think about the cases where you usually have it, you're trying to call a method on nil, it's because you're getting an object back that you didn't expect. And typically it's because you don't know what to expect.
Charles Max_Wood:
Right.
Valentino_Stoll:
And a lot of times clearing up, making it clear the inputs to methods or how data should be shaped within different objects, you can clean a lot of that up which kind of goes to like the whole typing argument.
Charles Max_Wood:
Yep.
Valentino_Stoll:
Which I'm not, I'm kind of with Luke on this. We're missing his, you know, scream into the void about it.
Charles Max_Wood:
Hahaha.
Valentino_Stoll:
But
Charles Max_Wood:
Yeah.
Valentino_Stoll:
I mean, I'm definitely on the air on the side of, you know, loving Ruby's dynamic nature and just being able to,
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
you know, treat everything like an object and worry about a later kind of
Charles Max_Wood:
Yep.
Valentino_Stoll:
When you do have specific things where you should expect these specific shapes of data and you want to, if it doesn't match that data, you want to know in advance when you're building stuff. I think this new data object just makes so much sense.
Charles Max_Wood:
Yeah. It was kind of interesting, I mean, looking at... not just the data, but some of the other things that they added to some of the other data structures too, like hash shift now always returns nil if the hash is empty, right?
Valentino_Stoll:
Yep.
Charles Max_Wood:
The module one is just refinements and stuff, which I never use refinements. You know, some of the syntax abstract syntax tree is kind of cool. the struct, you know, just cleaning that up and making it easy. I like that too. I also thought it was interesting they got rid of FixNum and BigNum.
Valentino_Stoll:
Yeah, I can't recall the time I've used them recently.
Charles Max_Wood:
Yeah, I don't know that I have either. I mean, if I use anything, I think it's big int instead of big num.
Valentino_Stoll:
Yeah, I've used Big End before.
Charles Max_Wood:
Yeah. Random double colon default. I don't know that I've ever used that either.
Valentino_Stoll:
What did that do?
Charles Max_Wood:
Beats the heck out of me. Um, a couple other ones that were interesting that got removed is, uh, deer or directory dot exists
Valentino_Stoll:
Yeah.
Charles Max_Wood:
and file dot exists. I've used that, I still use that, I don't know. I don't know if that's gonna hurt or if there's some other approach you're supposed to take.
Valentino_Stoll:
That's interesting. I don't... What? When did that happen? Ha ha ha.
Charles Max_Wood:
I mean it's listed here, but... says it's been deprecated since 2.1.0. Yeah, now I'm curious to know why. anyway. Anyway,
Valentino_Stoll:
Yeah, I forget.
Charles Max_Wood:
maybe they made the other ones kind of nil safe or something like that. Right, so if the file doesn't exist, then it just, you know, if you do file.read or file.whatever, it is smart enough to just... It was always a check I used to make sure that I didn't get an error when I tried to do those things.
Valentino_Stoll:
Yeah.
Charles Max_Wood:
If the file doesn't exist, because I would get an error saying that file's not there. So.
Valentino_Stoll:
Yeah, I know I used to use them for, you know, if this file exists, do this other process
Charles Max_Wood:
Right.
Valentino_Stoll:
otherwise, right? So I'm sure I'll have some scripts that no longer work.
Charles Max_Wood:
Yeah.
Valentino_Stoll:
That I'll have to be updating. We'll have to circle back and talk about that later
Charles Max_Wood:
Yeah, I agree. If somebody listening to this knows the answer, I'd be curious to hear it.
Valentino_Stoll:
Ha!
Charles Max_Wood:
I guess maybe you just rescue the error, right? but I don't like using that for that kind of control. right, a begin rescue block. I would rather do the check ahead of time and just let it flow through without having to rescue a file error.
Valentino_Stoll:
Yeah.
Charles Max_Wood:
Anyway, um, Colonel Taint, Colonel Trust, I never used those. I'm betting stuff I use uses or used those, but. Yeah, and then they also got rid of the equal tilde. which I've used for regular expressions. I don't. There are other ways to do the things that I've used it for, so I can kind of see why they might. Anyway, it's kind of interesting to dive in and see what's changed.
Valentino_Stoll:
Yeah, this is...
Charles Max_Wood:
So one other thing, yeah go ahead.
Valentino_Stoll:
I was just going to say that it looks like the equal tilde was removed from object.
Charles Max_Wood:
Yeah, it's showing it as kernel on the list that I'm looking at.
Valentino_Stoll:
Yeah. Maybe that's the same. Maybe they're synonymous.
Charles Max_Wood:
Yeah, could be. It could be because I think object inherits from kernel. I think just about everything inherits from kernel. Yeah, so on the list it says kernel dot, or kernel. But if you click the link for the feature, it says object equal tilde. So. Anyway, I'd be really curious to see how that. You know how that goes. I'm also curious, because I know a lot of people, and I'm one of these people, right, that are still running their code on Ruby 2, right? A lot of my stuff is still running on 2.7. I just never upgraded it. A lot of it was because it was on Rails, and there really weren't compelling arguments to move it to 3. But if you can turn on YJIT and get a 30%, 40% performance boost, at least on some of your code, starting to sound like it makes sense. Do you see people moving this way then? Or do you think people are going to kind of sit where they are until they have to move?
Valentino_Stoll:
Well, Ruby's end of life for 2.7 is up.
Charles Max_Wood:
Oh really?
Valentino_Stoll:
Uh, yeah, December 25th. So...
Charles Max_Wood:
interesting.
Valentino_Stoll:
Let's
Charles Max_Wood:
Yeah.
Valentino_Stoll:
see.
Charles Max_Wood:
Yeah. Two, two dot seven.
Valentino_Stoll:
Yes. Two to seven is not an end of life yet, but.
Charles Max_Wood:
No.
Valentino_Stoll:
point six is.
Charles Max_Wood:
Yep. It's interesting also to think that 2.7 came out three years ago. But yeah, it ends in two months and two weeks.
Valentino_Stoll:
Yeah, the clock is ticking
Charles Max_Wood:
I.
Valentino_Stoll:
y'all.
Charles Max_Wood:
Yeah, but again, I don't know that people are really compelled to move until there's a problem or until there's a major advantage.
Valentino_Stoll:
Well, you know, the biggest problem with having an end of life language is you don't get any security fixes.
Charles Max_Wood:
Right. Yeah, I understand that. And I agree that that's an issue. But again, I talked to a lot of people in a lot of companies that just aren't compelled to make a move until it bites them one way or the other. Or until they start doing an audit and realize, oh, you know, Ruby 3.2 is gonna get me major, it's gonna make a lot of things better for me. But most of the time it's cause it bites them or the security folks at their company that they work at go. You can't use this as end of life.
Valentino_Stoll:
Right.
Charles Max_Wood:
And I only see that really in the bigger companies. Most of the smaller companies that I've worked at, they just, it never occurred to them.
Valentino_Stoll:
Yeah, you know, when I did consulting, it was, you know, small businesses, businesses using Rails and, you know, a lot of them had somebody build something and it worked
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
and it continued to work for them, you know, for years and years. And, you know, they'd be on Rails 1, you know, with like the oldest, you know, 187 and
Charles Max_Wood:
Yep.
Valentino_Stoll:
it was working for them still. I can't imagine running that still. But who knows if they are still, right? Like,
Charles Max_Wood:
Yep.
Valentino_Stoll:
if you own your own server and you want to run that, who knows how they're being targeted? Unfortunately,
Charles Max_Wood:
Yep.
Valentino_Stoll:
nowadays, there are so many autonomous bots just crawling the web. Yeah, it would be interesting to find out. I'm sure there's got to be somebody with some research on who runs older versions of what the numbers actually are. Because I bet they're
Charles Max_Wood:
Right?
Valentino_Stoll:
a lot higher than I think.
Charles Max_Wood:
I think there are a lot of people running old versions. Yeah. And then they had some benchmarks in that, because you sent me a link to the Ruby Weekly. And so there were a bunch of benchmarks in there too. And what's fascinating to me is that some of the benchmarks, you can see a market improvement in some areas and others you really can't, right? It just kind of holds steady with past versions
Valentino_Stoll:
Yep.
Charles Max_Wood:
on some things and not others. And so I think, and this makes sense, right? improvements are in areas that certain functions or functionalities just use more.
Valentino_Stoll:
Yeah, I think a lot of it too is like, a lot of foundation is getting laid, right? So,
Charles Max_Wood:
Yeah.
Valentino_Stoll:
you know, you get what is the famous expression of, you know, make it easy to change and then make the easy change. Ha ha ha.
Charles Max_Wood:
Yep.
Valentino_Stoll:
I think just like a lot of groundwork is getting laid out to like build out, you know, kind of another layer to all of these new additions that will just bring those drastic improvements. I mean, I have a feeling,
Charles Max_Wood:
Yeah.
Valentino_Stoll:
you know, when we get to Ruby 4, if you compared it to Ruby 2, it would, you know, I just have a feeling that it's going to be a significant difference I mean, even if you just think now of Ruby 3 to Ruby 1, right?
Charles Max_Wood:
Yep.
Valentino_Stoll:
Like I feel like the difference has to be drastic. It's gotta be hard first to make a benchmark on something that old, but
Charles Max_Wood:
Yep.
Valentino_Stoll:
that could cross both. But I mean, it's gotta be drastic, right? Like.
Charles Max_Wood:
Yep, absolutely.
Valentino_Stoll:
But I mean, like I said, if you're just like a small business and you're not really using it to process anything,
Charles Max_Wood:
Yep.
Valentino_Stoll:
you know, you have five steps that your business goes through to get it to where it saves you the time and effort or solves a problem. I feel like for a lot of those cases.
Charles Max_Wood:
Yep.
Valentino_Stoll:
Yeah,
Charles Max_Wood:
It's.
Valentino_Stoll:
why bother?
Charles Max_Wood:
Yep. Yeah. I mean, I'm looking at some of these benchmarks, like there's the benchmark, uh, two six to three dot two from Thomas Leitner and he demonstrates that there are some improvements in some areas and his benchmarks included, um, hexa PDF. And cram down and geo M2D. Yeah, so like the Hexa PDF, there were speed ups in some with the 3.2 WaiJit, and in other areas it just really didn't seem to make much of a difference. doing just raw text, it, you know, again, it showed improvements in some areas and not much in others. Um, what, what I found interesting was you get down into the cram down and. Three, three.two is the slowest with cram down. which is a markdown parser, right? And then you turn the YJIT on and it performs as well as everything except for 3.1.3 with YJIT. And then you look at the GOM2D and the YJIT clearly makes a major difference. I don't know what GOM2D does, but it's instructions per second and it looks like the YJIT just really, you know, put some gas in the tank for how many instructions it can execute. Whereas without YGIT it seems pretty constant. So, anyway, kind of interesting. The other benchmark that I was looking at was from Peter Solnitsa. And he did it with Hanami's test suite. And Ruby 3.2 without YGIT actually outperformed Ruby 3.2 with YGIT. So... Anyway, just just kind of interesting stuff, right? And like you said,
Valentino_Stoll:
Yeah.
Charles Max_Wood:
you're probably setting the foundations for a lot of this stuff. But. Yeah.
Valentino_Stoll:
Hanami is wild.
Charles Max_Wood:
Yeah.
Valentino_Stoll:
I saw a benchmark the other day that they had to change their logger because some of the requests can be in microseconds response time.
Charles Max_Wood:
Uh huh.
Valentino_Stoll:
And so they had it in milliseconds and it, you know.
Charles Max_Wood:
Oh. That's funny. That's a good problem to have though, right?
Valentino_Stoll:
Right? They needed that new, you know, micro signifier.
Charles Max_Wood:
Right?
Valentino_Stoll:
But that's, I mean, that's pretty wild that you can get response times in Ruby in microseconds.
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
It's really, really impressive stuff.
Charles Max_Wood:
Oh yeah. I don't know if there's anything else to really dive into with this that I'm seeing. I just find it fascinating, kind of the steps forward that we're getting.
Valentino_Stoll:
Yeah, I mean, we'll see. I saw Aaron Patterson has a very entertaining year in review. That was a lot of fun to read through a lot of these highlights.
Charles Max_Wood:
Yeah,
Valentino_Stoll:
I'd recommend checking
Charles Max_Wood:
Aaron
Valentino_Stoll:
that
Charles Max_Wood:
is
Valentino_Stoll:
out.
Charles Max_Wood:
always entertaining.
Valentino_Stoll:
Yeah.
Charles Max_Wood:
Yeah, and it looks like it requires... That was another thing I saw in here, and I think we talked about when we talked to Takashi about this, but just that the... The YJIT makes Rust a requirement to compile Ruby.
Valentino_Stoll:
Yep.
Charles Max_Wood:
I mean, most of the tools I do, they just do it for me.
Valentino_Stoll:
Right, I mean if you're gonna be just downloading Ruby, you probably won't need to install Rust.
Charles Max_Wood:
Mm-hmm. Yeah.
Valentino_Stoll:
But I mean, it'll
Charles Max_Wood:
Oh,
Valentino_Stoll:
be
Charles Max_Wood:
here
Valentino_Stoll:
interesting
Charles Max_Wood:
we go.
Valentino_Stoll:
to see how
Charles Max_Wood:
Yep.
Valentino_Stoll:
that rust plays
Charles Max_Wood:
The,
Valentino_Stoll:
out.
Charles Max_Wood:
yeah, the year in review from, uh, Aaron Patterson, that's where he talks about the variable width allocation and. that kind of a thing in object shapes.
Valentino_Stoll:
Yep.
Charles Max_Wood:
So that's another resource. We'll put links to all this in the show notes. I've been adding some of these links to the, we have a collaboration forum that we use for a lot of this stuff. So I'm just gonna put a lot of these links in there, but yeah, very cool stuff. So
Valentino_Stoll:
Yeah, I mean, next
Charles Max_Wood:
I...
Valentino_Stoll:
to that, I would say, you know, a lot of the IRB stuff is really fun too.
Charles Max_Wood:
I don't know if I saw that.
Valentino_Stoll:
So IRB has become its own gem now, so
Charles Max_Wood:
Oh, okay.
Valentino_Stoll:
You you can it's bundled like a lot of the other default gems are
Charles Max_Wood:
Mm-hmm. Yeah, but it can evolve independent of Ruby
Valentino_Stoll:
But yeah,
Charles Max_Wood:
now.
Valentino_Stoll:
lots of new keywords have come to IRB sessions now to mimic a lot of what was missing from what Pry has added over the years,
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
right? So
Charles Max_Wood:
Yep.
Valentino_Stoll:
you can show commands and LS methods and just like a ton of debug stuff. So you can finally step through Ruby code in a visually appealing way without needing RubyMine or something like that to do that for you.
Charles Max_Wood:
Yep. Yep. That's interesting. Another interesting one, yeah, I found that in this list here, is the bundler you can do a double dash ext equals rust if you have a rust extension and it'll build it.
Valentino_Stoll:
Oh, that's cool.
Charles Max_Wood:
Yeah. I think most of the ERB stuff is just performance stuff.
Valentino_Stoll:
But why use the RB when you've got Hamil? Ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha ha
Charles Max_Wood:
I feel you there. I moved one of my projects over to Hamill and the migration was a little bit painful, but oh my gosh, is it so nice. It's like, I don't have to scroll down 10 years to figure out where the closed div is that I missed.
Valentino_Stoll:
Right.
Charles Max_Wood:
So one thing that I did run into though is that when you run the HTML to Haml script, it didn't pick up the web components folder. And so I've, I've got to figure out how to run it on that. I think you'd just have to tell it to run it on that folder. I just haven't done it yet,
Valentino_Stoll:
Mm.
Charles Max_Wood:
but that way I would be super helpful too. Anyway, I think like I said, I think we're kind of at the end of this discussion. So let's go ahead and move into the... the self promo before we do the picks. So is there anything you're working on you wanna let people know about?
Valentino_Stoll:
Ah, yeah. I've been working with OpenAI's API recently at work
Charles Max_Wood:
Oh nice.
Valentino_Stoll:
to help generate insurance denial letter-like responses. So
Charles Max_Wood:
Oh wow.
Valentino_Stoll:
there's a Twitter video of some doctor Yeah. Showing how to use chat GPT to,
Charles Max_Wood:
Uh
Valentino_Stoll:
you
Charles Max_Wood:
huh.
Valentino_Stoll:
know, generate, you know, all of my, you know, patient got denied this in, you know, medication that they need. So, you know, here we go. We're going to eat. It's like, it's just like, you know, GFGI vote for chat GPT. Oh yeah. Generate me a letter appealing this denial from this insurance company.
Charles Max_Wood:
Yeah,
Valentino_Stoll:
And so
Charles Max_Wood:
that's interesting because I've
Valentino_Stoll:
yeah.
Charles Max_Wood:
experienced that. I switched insurances and the new insurance denied the medication I was on. And they basically told the doctor, you have to try these other ones first.
Valentino_Stoll:
Yeah.
Charles Max_Wood:
So I'm on the other ones. Anyway, it's kind of interesting.
Valentino_Stoll:
But yeah, so I've been playing with their API and worked with a bunch of teammates to kind of build that around this chat GPT, training some new models and trying out a bunch of stuff with their API. And it's just so much fun. It's kind of incredible what you can do with it.
Charles Max_Wood:
Yeah.
Valentino_Stoll:
They're so opinionated and they make it up. You
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
have to heavily edit them. But
Charles Max_Wood:
Right?
Valentino_Stoll:
at the same time, it's just so much fun. You can play with how much that it changes the response from
Charles Max_Wood:
Mm-hmm.
Valentino_Stoll:
when you ask at the same thing every time. There's just so many things you can tweak on it. I've just been having a blast.
Charles Max_Wood:
Right, no, this isn't a form letter, it's an AI-generated letter.
Valentino_Stoll:
Right. Yeah, I've been seeing a lot of that actually deciphering whether or not chat GPT generated it, right?
Charles Max_Wood:
Yeah. Oh yeah. I've seen threads. I ran for school board this last year and so I'm still in a lot of the education spaces and yeah, seeing people go, okay, well, we were worried about plagiarized content on the internet before.
Valentino_Stoll:
Ha ha ha!
Charles Max_Wood:
Now we have to figure out whether or not an AI wrote it or a student wrote it. Oh, so fun. Yeah, I've been playing with some of the AI stuff too. I think I'm gonna just pick it in my picks though. For the stuff that I'm working on, I'm gearing up to release a course. The course is basically going to be how to consistently and in many cases, quickly advance your programming career. I've talked about my process before, so it's not gonna be a major secret, in the course, right? So when I talk about, hey, you need to learn something new every day, it's going to be, hey, you can learn it from YouTube videos. Here's how you find the relevant stuff. Find relevant blog posts, find relevant books, find relevant podcast episodes, on and on and on, right? And then when it's commit code every day, it's like, here are several things that you can do to make sure you're committing code every day with the stuff you're learning. Walk people through how to create a media channel and post to it every week. These are all parts of the process. How to find a solid meetup you can go to, how to find a conference you can attend, whether you can afford to travel or not. If you can't, then okay, how do you find the kinds of summits or opportunities or are paying for remote tickets to things like Rails Comfort that are stuff like that. to how you evaluate that and how you figure it out. So anyway, that's gonna be the next course and it's gonna talk about how they all kind of play together to put you in the best position to either change jobs to the one you want or put your best foot forward where you are or go freelance or whatever that next stage is, how to submit talks to conferences if that's your next stage and stuff like that. So there's gonna be a lot of that stuff covered do it. And then yeah, I'm planning on having more courses put up, like for example, submitting to conferences. That's probably a full course on its own, but I can give you the fundamentals in the course to get you started if you just don't even know where to go. Right. But a lot of the other stuff, it's like, how do you stay current? Well, you know, I have a whole process for that and I'll just show you the whole dang thing. Right. Because there's not a whole lot of nuance to that. Not a whole lot of conditions to that. The internet works. pretty much the same way and people figure that out. So keep an eye out for that. And then I'm going to start a new podcast this next week. It's going to be called Catapult Your Coding Career. And we're just going to talk about, I've been coaching people for the last year or so, and I'm just going to talk through, you know, some of the things that they bring up and just quickly answer questions. I'm hoping to put out, I think I'm going to start with three episodes per week. each and it's gonna be hey here's the question here's the answer right and if there's more nuance to it I mean it may be here's the question and if this is your circumstance here's the answer for 10 minutes and then the next week is if this other circumstance applies here's your answer right but I want to give people the tools to be able to have what they want with their career and I just don't see a lot of people talking about it I see some general stuff about advice or find a new job, but I don't see a lot of people talking about it with programming jobs. In a lot of cases, the other thing is I see people feel like they're boxed into a certain kind of job, and the reality is you don't have to be. I just want to help people see their options, see their opportunities, and then be putting themselves in a position with their learning to where they can just take advantage of stuff that comes their way. Anyway, that's what I'm going to be covering there. for coaching, right? And so if you feel like you need more than the 10 minutes at a time, right, then you can come talk to me and we'll figure something out. That's also why I set up the top Endeavs membership was so that I could provide kind of a higher level of that to people who sign up for the membership and not have it cost several hundred dollars a month like the That's kind of the big thing that I've got rolling this month. And then you may see some changes on the top end devs website, and I'm going to pick stuff related to that here in a minute. So anyway, that's what I'm working on. That's the exciting stuff. I have a whole list of other things that I want to do and that are not quite ready to be announced. So anyway, let's go ahead and do some picks. Do you have some picks, Valentino?
Valentino_Stoll:
Yeah, I have a pic. I was playing with some voice cloning and recognition software from resemble.ai. Pretty wild platform.
Charles Max_Wood:
Ah.
Valentino_Stoll:
A
Charles Max_Wood:
You're
Valentino_Stoll:
lot
Charles Max_Wood:
doing
Valentino_Stoll:
of fun.
Charles Max_Wood:
some Donald Trump deep fakes, huh?
Valentino_Stoll:
Well, no, I use, they have an Alexa skill
Charles Max_Wood:
Okay.
Valentino_Stoll:
template, so you can basically use your own custom voices for your Alexa skill
Charles Max_Wood:
Uh huh.
Valentino_Stoll:
and use some like text-to-speech stuff so you can like kind of have a conversation and use like different voices than Alexa's voice if you wanted to as an example. So I've been playing with that kind of just for fun. goes. Just a lot of fun.
Charles Max_Wood:
Awesome. Um, I'm going to throw in some other AI stuff. So one of the ones that I found that I really like is called mid journey. And so I signed up for it. A free account gets you like 20 images or 20 queries or whatever. I can't remember. I'll have to go look it up for you all can go look it up, but effectively what it does is it, you get added to a discord server and then you give it the hashtag slash imagine, and then you just type in your query, right? And so you say, I want, and I've used this putting together the newsletter, right? But it's effectively tells you, I want this kind of setup or this kind of a thing with this style. So you can tell it like video game style, or you can tell it hyper realistic. You can tell it like 8K. And you can tell it that you want to see all kinds of stuff. And anyway, it's really cool. So some of the images that I've gotten back from it, I've been pretty happy with. And what's interesting too is that they're AI generated, so they're all original. I mean, original-ish, right? Because they have fed in a ton of artwork with keywords on it and trained the AI. So some of it looks derivative. to be careful with some of that, right? Because if you put in like the name of a real person, it will generate artwork with the face of that real person, right? And so there are laws about how you do some of that stuff. But you know, if you're being a little more generic, you can get all kinds of interesting stuff. So I'm going to pick that because I've really liked it. You can also type in something like, you know, a woman that blah, blah, blah, blah blah blah. One of the ones I put in was a woman listening to a podcast about programming, this, that, and the other. It generated a face. Now, I'm sure it looks like somebody out there, but it didn't look like anybody that you would pick out of a crowd because you recognize the face. Anyway, Mid Journey is really cool and I'm really digging it. I have been playing with chat GPT as well. And one of the things, so I've had people basically tell me how useless it is. And in a lot of the use cases they're trying to use it for, I can see that it really, it just hasn't been trained in those areas. And it also makes mistakes fairly frequently. So in a lot of cases, you really can't use it just straight up for your... you know, your thing to write your content. But the thing that it does do for me, at least, that I like is when I'm trying to put together a message about a topic, again, for the mailing list or things like that, that's primarily where I've been using it. I can get it to explain to me some thing that I'm thinking about and give me ideas of where to go from there. And then I can actually ask it another question and dig deeper in those areas and see what it comes back with. refine my thoughts and in a lot of cases, it organizes things in a way that I like. Not always, sometimes it's weird, but it's a nice way to go, so I'm liking that. I realized that we were talking about AI and I skipped the board game pick, so I need to go back and do that real quick. Now I'm going to pick a kids game. This is one. I think it was last Christmas, we got her a game called Sleeping Queens. And Sleeping Queens, what it is, is you, there are special cards, there are sleeping potions, there are knights and dragons and kings. And um... you use the... are there kings in that one? There are kings in the second one. But anyway, what you do is you use the knight to rescue the queen. No, the knights protect your queen, so it is the king. You use the king to wake up the queen. The dragons steal a queen and the knights protect it. The sleeping queens put the queen to sleep and the wands keep have numbered cards. And so you can trade in cards to get new cards on your turn, instead of playing a card and then drawing back up to turn your hand over faster. But they have to work out to a math problem, right? So it can be like 2 plus 2 equals 4, or 4 equals 4, or 3 times 5. There aren't 15s, but 2 times 5 equals 10, right? And so you can get rid four equals 10, right? You get rid of your whole hand because you have five cards in your hand. And so it's pretty simple. Board Game Geek weighted it at like 105, 1.05. So it's a really simple game, but she really loved it. And it was something we could all play, right? And it's fast paced and interesting enough for us to play it. I'm also gonna pick Sleeping Queens 2, which is a little more involved. Board Game Geek, last time I looked, hadn't rated it, I hadn't ranked it yet a newer game. But effectively there the difference is you have to have a queen and a an animal companion to rescue a king. And then there are cards that make you swap cards, you do the math problems to get the animal companions, and so it's a little more involved. I would guess it's probably a 1.5 on Board Game Geek once they get a weight on it. So anyway, fun games if you've got eight years and older. But like I said, my seven year old plays it. My six year old, when she was six, she didn't have any trouble playing it. So if you're looking for a fun fantasy themed game, yeah, pick it up. And all the kings and queens have themes to them. So they have like the... the cookie king and the kitty queen and the dog queen. They're all dressed up and drawn with stuff with their themes. So anyway, it's pretty fun. So I'm going to pick that. I think that's about it. I guess the only other pick that I have is we're into next year or we're into this year, however you want to say that. So I've been catching up on my bookkeeping so I can file my taxes, which is not my pick because I think I get ripped off with that. But... I've been using Xero to do my bookkeeping for the last couple of years, and it is so much easier than QuickBooks. So I'm going to pick Xero.
Valentino_Stoll:
I've
Charles Max_Wood:
And
Valentino_Stoll:
heard good
Charles Max_Wood:
I guess
Valentino_Stoll:
things
Charles Max_Wood:
we'll,
Valentino_Stoll:
about Zero.
Charles Max_Wood:
yeah, it's really nice. It's funny because I have a number of friends that do different kinds of business consulting and they swear by a quick books. But the thing is, is that every time I thought I understood what I needed to do in it, there was always some other edge case with my books that just caused headaches and zero keeps it a lot simpler. And zero also does the invoicing and stuff like that. I mean, any more I use. me for something, I just send them a Stripe link, right? Because you can create a product and send them a link. But that's not to say that, you know, sending an invoice through Xero isn't sometimes the better option. And it does everything else that I need to do. I used to use fresh books, and it worked great for invoicing and I didn't like it for bookkeeping. But yeah, the invoicing and stuff in Xero works fine. I'm pretty happy with it. So So yeah, so I'm going to pick them too. All right, well, let's go ahead and wrap it up here. Thanks for jumping in on this, Valentino.
Valentino_Stoll:
Yeah, it was a lot of fun, there's a lot of good stuff coming.
Charles Max_Wood:
Yep, absolutely. And maybe we'll, I'm looking at deploying some of my stuff and upgrading Rails and Ruby, and then just maybe we can do an experience report of some kind.
Valentino_Stoll:
Yeah, take some notes.
Charles Max_Wood:
Yeah, one other thing I was going to throw out real quick before we wrap up is the book club. We've been talking about what we wanted to learn next, the handful of people that have been in there. And it's been fun because Uncle Bob's been coming for clean architecture. But what we're looking at next is doing some kind of container Kubernetes deployment book and working through that and talking through that. So if that's kind of something that you're looking to learn, that's definitely an area that I wanted to focus on in top end devs as well. It'll probably generate some courses and stuff in there as well. But sign up for the book club if you're interested because we're going to start that in February. And I guess we'll end it there. Until next time, folks, Max out.
Valentino_Stoll:
Later.