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.)
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
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.
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 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.
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).
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.
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.
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.
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.
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).
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.
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.
_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.
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.
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.
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?
>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.
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.
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.
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.
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/
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.
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
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.
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:
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.
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.
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.
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.
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.
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.
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.
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.
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!