Tempfile.create(anonymous: true) removes the created temporary file
immediately. So applications don’t need to remove the file.
[Feature #20497]
I use a similar pattern a lot:
file = Tempfile.new.tap(&:unlink)
file << "... some really large data to pipe"
system("md5sum", in: file.tap(&:rewind))
It's a neat trick to leverage the filesystem for large amounts of data (e.g. "psql \copy" generation), without littering tempfiles everywhere. Once the last fd disappears, the filesystem releases the data; so you don't have to "trap" signals and add cleanup routines. (Hint: you can also use these unlinked-tempfiles for command output, e.g. huge grep output, etc.)
On Linux systems, `open(..., O_TMPFILE)` is typically used, which provides additional safety. The created file is initially unnamed (no race condition between `open` and `unlink`).
When I needed safety, my non-portable solution was to use Ruby's syscall feature. (Btw, I love that you can do this.)
Linux 3.11 has O_TMPFILE to create an unnamed file.
The current implementation uses it.
Excellent to see :)
Makes the PR even better!
15155 49 days ago [-]
This is available in older Ruby versions by using the upstream `tempfile` gem version.
Trasmatta 51 days ago [-]
The default block parameter name seems small, but I feel like I'm gonna use it all the time, especially when I'm in the Rails console just trying to debug data
lucasoshiro 51 days ago [-]
Kotlin also has it, I can tell you that it's really useful
cempaka 51 days ago [-]
Ruby has had this in the same form as "_1" for a while (and the obvious other indexes in the case of multiple params), but I agree Kotlin's "it" reads much better.
onedognight 51 days ago [-]
Groovy has had “it” for a while. I suspect it predates Kotlin’s usage.
Also damn Nim needs to do a much better job with their docs and site. `nim result` returns this very outdated third-party link first and nothing else official.
jarjoura 51 days ago [-]
I constantly run into situations where I need to nest an iterator computation, and things like "it" get confusing.
I'm all for adding language features to avoid boilerplate, and it's clearly useful. I just want to call out that anonymous typing can be polarizing in large codebases and maybe only use it sparingly.
Trasmatta 51 days ago [-]
I doubt I'll use it in committed code very often at all, this feels more like something that's very useful when hacking at something in the REPL
51 days ago [-]
elif 51 days ago [-]
nested_example = [1, 2, 3, 4, 5].map do
[it, (1..it).map { it * it }]
end
Has an ambiguity, so you just add |x| to one of them..
nested_example = [1, 2, 3, 4, 5].map do |x|
[x, (1..x).map { x * it }]
end
Seems like a mental over complication of a non-issue to me.
snuxoll 51 days ago [-]
Implicit `it` shadows in other languages like Kotlin just like any other variable scope, and I really can’t say I’ve ever had it be a problem (implicit receivers, on the other hand, can be a right pain in the ass in poorly designed libraries and can I just say Gradle can go right to hell for it).
jarjoura 51 days ago [-]
It’s a nonissue in small projects, but I’m not sure I agree that `{ x * it }` is easy to reason about when coming back to this block in 6 months. It’s mostly something that I’ve seen bite engineers during refactoring.
tyre 51 days ago [-]
Being ruby you can monkey patch block to add an additional t to every nested block’s `it`
(This is terrible please don’t)
regularfry 51 days ago [-]
I've not been tracking ruby core discussions for ages now, but I could have sworn that exactly this was discussed and rejected a decade or so ago.
faitswulff 51 days ago [-]
I think I remember that as well. If you read the changelog, it goes through a good deal of edge cases behaviors that they probably ironed out in the intervening time, like captured variables with the same name and nested blocks with it parameters.
Spivak 51 days ago [-]
I was disappointed that "block parameter name" wasn't the ability to give a block an actual name that will show up in a stack trace. It's been an endless source of frustration when your stack trace is just a bunch of anonymous blocks and procs. I assume JS devs feel a similar pain with anonymous functions.
allknowingfrog 50 days ago [-]
We already had "_1", "_2", etc., for inline block arguments. Adding "it" increases the surface area of the language without adding any new functionality. I think the underscored names are actually better for readability. They jump out at me, while "it" looks like every other variable name.
items.map { foo(_1) }
items.map { foo(it) }
block_dagger 51 days ago [-]
I like “it” but it’s a shame it works only in single line blocks.
tiffanyh 51 days ago [-]
I know Shopify has a great site on comparing Ruby vs YJIT perf.
And for an appearance of comparability the "#8" programs are un-optimised single-thread transliterated lowest-common-denominator style into different programming languages from the same original.
> In Ruby 3.4, it has been added as a default name for the first parameter passed to a block. Rather than specifying a name in trivial cases like the one above, you can now write:
> [
> "beige chinos",
> "blue jorts",
> "rainbow jorts",
> ].filter { it =~ /jorts/ }
> # => ["blue jorts", "rainbow jorts"]
This reminds me of Perl's $_ (which in Ruby is last line read from STDIN).
jshmrsn 51 days ago [-]
I am familiar with ‘it’ as a default closure input from Kotlin. From a quick search, that in turns seems to be inspired by Groovy.
Is the stack trace in the section "Clearer exception backtraces" actually from 3.4? It has mixed backticks and single quotes.
Sinjo 51 days ago [-]
Fixed! I grabbed that example from the bug tracker issue where the change was discussed and that wasn’t based on a version where the backtick change had been made.
kace91 51 days ago [-]
I happen to be reading the latest edition of the pickaxe book, as I'll soon be using Ruby at work (first experience) and this 'it' update sounds so much better than the _1 described in the book.
I remember thinking it clashed a bit with the idea of trying to make the code read like natural language.
jaynetics 51 days ago [-]
_1 is also a bit of a footgun. It becomes an array of all block params IF the block has an arity > 1 AND no other block param (e.g. _2) is referenced anywhere within the block.
It's an unusually half-baked feature by Ruby's standards. I think there was some hesitation about the name "it" initially, because "it" is an essential method name in rspec, and is used within blocks there.
ryanmjacobs 51 days ago [-]
Oh damn. I have been using `_1`, `_2`, etc. extensively for years... I didn't know about that footgun.
I'd like know if `it` is merely an alias for `_1`, or if protects from this "arity issue" too.
ch4s3 51 days ago [-]
I pity anyone needing to debug a fiddly Rspec problem in the next few years.
ezekg 51 days ago [-]
IIRC, the decision was that it in a block is only ever called without arguments, e.g. map { it * 2 }, and it in Rspec is only ever called with arguments, e.g. it "describes a test" do ... end. So it ended up being a non-issue.
ch4s3 51 days ago [-]
I can totally see some add on gem for rspec breaking that assumption.
ryanmjacobs 51 days ago [-]
FYI, one of my favorite Ruby idioms is to capture command output with `open(...){_1.read}`
Am I missing something - it's 2am here, so possibly - or could you not just use backticks for the first one?
ryanmjacobs 50 days ago [-]
Oh that's embarrassing -- you're right, the first example doesn't make sense. Kinda pointless actually haha
I use it for code like this:
raw = IO.popen(%W[gzip -d -c -- #{path}]){_1.read}
raw = IO.popen(%W[gzip -d -c], in: pipe){_1.read}
raw = IO.popen(%W[git status --porcelain -- #{path}]){_1.read}
Useful because it eliminates /bin/sh footguns (e.g. `md5sum hello&world` forking or `~john` expanding), plus you get kernel.spawn() options. `open("| ...)` only made sense for the second example.
Anyway, I find "_1" more eye-pleasing than:
IO.popen(%W[gzip -d -c #{path}]){|io| io.read}
ksec 51 days ago [-]
Did you know you were going to use Ruby before Applying? Just wondering.
kace91 51 days ago [-]
Yup. I don't mind switching languages, I've done it a few times and I enjoy learning new things.
The market for ruby seems to have good salaries and job satisfaction despite being smallish, so it didn't seem like a bad area to get some experience in.
Why, is there any issue with the choice I'm not aware of?
ksec 51 days ago [-]
>Why, is there any issue with the choice I'm not aware of?
No, not at all. I was just interested since there is a sudden influx of people joining Ruby ( I guess mostly Rails ) companies without previous Ruby background. As I have notice this across HN, Reddit, Twitter and elsewhere. And yes Ruby market tends to be on the slightly higher end because they mostly hire people with years of programming experiences and lack of junior position. And there used to be complains about not being able to find people with Ruby / Rails experiences etc. So it is a good market shift I guess.
kace91 51 days ago [-]
Ah well, as soon as I even glanced at Ruby my social media feeds were filled with tech influencers.
There is a niche there of very popular channels producing Ruby tutorials, seemingly aimed at the junior js-bootcamp dev crowd. They also focus on Neovim, tmux and other terminal based tools.
It is a completely anecdotal observation, but my guess is that it might explain part of the trend.
hit8run 51 days ago [-]
I have a love-hate relationship with Ruby. On one hand, it's a very expressive language that's excellent for building structured, lightweight applications. On the other hand, it requires significant discipline and a strong memory of your codebase and all the different types in play. When you combine this highly dynamic nature with Rails, especially its concerns and hooks, it can become extremely challenging to understand what's actually happening in the system.
magic_smoke_ee 50 days ago [-]
I don't understand the change of the default block parameter name. It's already _1, _2, etc. Why create yet another, backward-incompatible way?
And still, they doom march forward with the fragmentation of rbs and sorbet/tapioca, rather than adopting in-band gradual typing like Python did.
I think the greater problem is Ruby appears to be developed by a nearly-closed small clique of people who refuse to listen to others or to reason.
allknowingfrog 50 days ago [-]
I agree that `it` is unnecessary, but I'm really confused by the push for a type system. It adds a lot of clutter to a language that optimizes for expressiveness. I would prefer to work in something like Go, which is designed to have types, rather than awkwardly patch them into Ruby.
magic_smoke_ee 50 days ago [-]
Apples (dynamic language) vs. oranges (static languages). Python's gradual typing approach solved this problem similarly to TypeScript, which is the right way to do it: https://peps.python.org/pep-0483/
allknowingfrog 50 days ago [-]
It may be less bad, but I don't think there's a right way to retroactively add a type system to a dynamic language. I generally like working in JavaScript, but I have no desire to ever see TypeScript again.
behnamoh 51 days ago [-]
Is ruby used outside of web dev (i.e., Ruby on Rails)? it seems like a nice cute language but I almost never hear about it.
lucasoshiro 51 days ago [-]
I think it's quite sad that Ruby is so associated with Rails. Ruby is one of my favorite languages and last time that I touched a Rails code was in 2017. Even in web dev Rails is not the only thing in Ruby, there's also Sinatra which is an elegant micro-framework for building HTTP APIs, similar to Flask.
Some projects that I remember that uses Ruby that are not related to web dev: Homebrew, Metasploit, Vagrant and Jekyll.
I also find Ruby very useful for shell scripts. I wrote a blog post about that some months ago, you can read it and the discussion about it here: https://news.ycombinator.com/item?id=40763640
watercolorblind 51 days ago [-]
Some other examples: DragonRuby, and Chef (which I prefer over ansible).
UncleOxidant 51 days ago [-]
I got into Ruby kind of early, around 2001. When Rails initially came out a few years later (circa 2004, IIRC) I remember being excited to see something putting Ruby out there giving it some publicity. But in a few years I think a lot of us were regretting the fact that most people's view of Ruby was formed by Rails.
Levitating 51 days ago [-]
Congratulations on getting Matz to tweet about your post.
lucasoshiro 51 days ago [-]
Thanks! I never thought this would reach him!
omoikane 51 days ago [-]
Ruby is my go to language for short "fun" programs, as there are many places where it optimized for development experience (such as the new "it" feature). One of the committers, Yusuke Endoh, clearly understood the joy of coding in itself as opposed to being means to an end, and has authored a book on esoteric programming:
Before Ruby, my preferred fun language was Perl. Ruby is like Perl but without having to type $ all the time. I have never used Rails.
Alifatisk 51 days ago [-]
Oh yes, Ruby is my go to language to use when I need to glue things together or when I want to automate tasks on my computer. It's such a pleasant language to use!
I think the reason it's not talked about a lot is mainly because Rails overshadowing it and because there aren't so much hype or controversies around it.
cempaka 51 days ago [-]
At my day job we use Ruby with Sorbet to stitch together a large number of data engineering pipelines. It's a good choice since we also often stand up small Rails apps to expose the results from those pipelines, so we can keep everything in one language. The fluent functional approach it enables is pretty nice for that business logic (but I would not want to do it without the gradual typing on top). We do find ourselves glancing over at the Python ecosystem with envy from time to time but overall it has worked pretty well. As I've gotten better with it I find myself reaching for irb for more and more one-off tasks in the shell too.
Sinjo 51 days ago [-]
Oh nice! I haven't used Sorbet yet, but this is the second time I've heard good things about it outside of Stripe (where it originated). I'll have to give it a proper look.
cempaka 51 days ago [-]
I think they direct people to tapioca by default at this point, but that was key to making it a smooth process for us.
gejose 51 days ago [-]
I find it to be a mixed bag. Better than nothing, but doesn't come anywhere close to what something like typescript can do for example.
petre 51 days ago [-]
Yup, I wrote smartcard reader programs in it. Some of them talk to a http server using async-http. It can be used for anything that Perl or Python is good at, well maybe except data science because Python really shines there. And irb is massively useful for everyday tasks.
cempaka 51 days ago [-]
I wish I could reach for Kotlin as a kind of "Ruby with typing out of the box" but the lack of a good REPL is a real dealbreaker.
Alifatisk 51 days ago [-]
You'll get Ruby with typings soon when rbs-inline is finalized
cempaka 51 days ago [-]
Is that really something that's been slated to be added to the language proper? I attended RubyConf and in his keynote Matz seemed pretty opposed to adding types to Ruby source, and argued in favor of automatic typing instead.
petre 51 days ago [-]
You can always use Crystal or Dart if you want builtin types. I like Ruby the way it is an trust Matz with his language design decisions.
Alifatisk 51 days ago [-]
Crystal is the closest alternative to Ruby with types we have, even though they are semantically different and differ in some places. I do not see why you mentioned Dart as an alternative thought, it’s a totally different language.
petre 50 days ago [-]
> Dart as an alternative thought, it’s a totally different language
Yes it's not Ruby but it has good design, optional type annotations.
cempaka 51 days ago [-]
Yeah I actually did not necessarily mean to dispute Matz's perspective there. I actually think it will benefit programming as a whole if at least one widely used language takes the path of trying to eschew explicit type annotations.
Sinjo 51 days ago [-]
Ooh, I hadn't heard of rbs-inline before. I was always a bit put off by the type definitions having to live in separate files.
Levitating 51 days ago [-]
Yes! In practice it's a scripting language similar in vein to Python, and it's used for similar things.
It's actually the language of choice for a lot of OpenSUSE projects as well, like the Open Build Service.
The reason you don't here much about it is because of its maturity.
thayne 51 days ago [-]
It's used for chef/cinc. I rather like that "recipes" use ruby with an edsl rather than yaml like ansible or salt.
dismalaf 51 days ago [-]
Vagrant, chef, puppet and lots of other stuff is written in Ruby. It's also great as a scripting language replacing Bash, Python or Perl for any number of things. I write all my small, one off programs in Ruby.
inopinatus 51 days ago [-]
I use Ruby extensively in ops scripting and text mangling, where it supplanted Perl for me around about the same time that Perl stagnated ca.2010-2015.
However, Ruby doesn't make sense to me as a general applications language (Swift & Kotlin have won me over from C++ & Java), or as a systems programming language (I'm still rusted on to C, pun intended), and I remain super ambivalent about Rails despite using it extensively to stick web interfaces onto things. That doubt is in large part because Rails frequently undermines the Smalltalk-ish heart of Ruby.
baggy_trough 51 days ago [-]
Sure. I use it for almost everything, because it's so pleasant to use.
Toutouxc 51 days ago [-]
Yeah, I use it for everything between 5-lines-of-bash and a needs-a-compiled-language. You almost never hear about it, because it's mature. No big controversies, no huge fuckups or new versions that break everything, just a steady trickle of improvements.
AnthonBerg 51 days ago [-]
I am happy in this moment because as I lay here with my ear on the ground, I can hear many many people hearing about Ruby
segfaltnh 51 days ago [-]
We use it for microservices that only deal with Json and avro. Of course, we do that on Rails for some reason I'll never understand.
Trasmatta 51 days ago [-]
Definitely, although Rails is its most common use
cess11 51 days ago [-]
You might have heard about Metasploit.
baggy_trough 51 days ago [-]
Happy to see chilled strings; eventually getting rid of the frozen strings pragma will be enjoyable.
On Linux systems, `open(..., O_TMPFILE)` is typically used, which provides additional safety. The created file is initially unnamed (no race condition between `open` and `unlink`).
When I needed safety, my non-portable solution was to use Ruby's syscall feature. (Btw, I love that you can do this.)
But... Another pleasant surprise from the PR (https://bugs.ruby-lang.org/issues/20497). Excellent to see :) Makes the PR even better!Also damn Nim needs to do a much better job with their docs and site. `nim result` returns this very outdated third-party link first and nothing else official.
I'm all for adding language features to avoid boilerplate, and it's clearly useful. I just want to call out that anonymous typing can be polarizing in large codebases and maybe only use it sparingly.
Has an ambiguity, so you just add |x| to one of them..
nested_example = [1, 2, 3, 4, 5].map do |x|
endSeems like a mental over complication of a non-issue to me.
(This is terrible please don’t)
https://speed.yjit.org
But does anyone have current numbers on how Ruby/YJIT compares to something like Python/PHP/LuaJIT?
Ruby+YJIT vs Python: https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Ruby+YJIT vs PHP: https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Ruby+YJIT vs Lua: https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
> [
> "beige chinos",
> "blue jorts",
> "rainbow jorts",
> ].filter { it =~ /jorts/ }
> # => ["blue jorts", "rainbow jorts"]
This reminds me of Perl's $_ (which in Ruby is last line read from STDIN).
Ruby 3.3
> 'asd' + 1 (sitar-report):1:in `+': no implicit conversion ...
Ruby 3.4
> 'asd' + 1 (sitar-report):1:in 'String#+': no implicit conversion...
EDIT: https://en.wikipedia.org/wiki/Backtick#As_surrogate_of_apost... seems relevant
I remember thinking it clashed a bit with the idea of trying to make the code read like natural language.
It's an unusually half-baked feature by Ruby's standards. I think there was some hesitation about the name "it" initially, because "it" is an essential method name in rspec, and is used within blocks there.
I'd like know if `it` is merely an alias for `_1`, or if protects from this "arity issue" too.
I use it for code like this:
Useful because it eliminates /bin/sh footguns (e.g. `md5sum hello&world` forking or `~john` expanding), plus you get kernel.spawn() options. `open("| ...)` only made sense for the second example.Anyway, I find "_1" more eye-pleasing than:
The market for ruby seems to have good salaries and job satisfaction despite being smallish, so it didn't seem like a bad area to get some experience in.
Why, is there any issue with the choice I'm not aware of?
No, not at all. I was just interested since there is a sudden influx of people joining Ruby ( I guess mostly Rails ) companies without previous Ruby background. As I have notice this across HN, Reddit, Twitter and elsewhere. And yes Ruby market tends to be on the slightly higher end because they mostly hire people with years of programming experiences and lack of junior position. And there used to be complains about not being able to find people with Ruby / Rails experiences etc. So it is a good market shift I guess.
There is a niche there of very popular channels producing Ruby tutorials, seemingly aimed at the junior js-bootcamp dev crowd. They also focus on Neovim, tmux and other terminal based tools.
It is a completely anecdotal observation, but my guess is that it might explain part of the trend.
And still, they doom march forward with the fragmentation of rbs and sorbet/tapioca, rather than adopting in-band gradual typing like Python did.
I think the greater problem is Ruby appears to be developed by a nearly-closed small clique of people who refuse to listen to others or to reason.
Some projects that I remember that uses Ruby that are not related to web dev: Homebrew, Metasploit, Vagrant and Jekyll.
I also find Ruby very useful for shell scripts. I wrote a blog post about that some months ago, you can read it and the discussion about it here: https://news.ycombinator.com/item?id=40763640
https://www.amazon.co.jp/dp/4774176435
Before Ruby, my preferred fun language was Perl. Ruby is like Perl but without having to type $ all the time. I have never used Rails.
I think the reason it's not talked about a lot is mainly because Rails overshadowing it and because there aren't so much hype or controversies around it.
Yes it's not Ruby but it has good design, optional type annotations.
It's actually the language of choice for a lot of OpenSUSE projects as well, like the Open Build Service.
The reason you don't here much about it is because of its maturity.
However, Ruby doesn't make sense to me as a general applications language (Swift & Kotlin have won me over from C++ & Java), or as a systems programming language (I'm still rusted on to C, pun intended), and I remain super ambivalent about Rails despite using it extensively to stick web interfaces onto things. That doubt is in large part because Rails frequently undermines the Smalltalk-ish heart of Ruby.