Hacker News new | ask | show | jobs
by area51org 1283 days ago
I appreciate the Ruby love in this post, but it's worth pointing out that the author is clearly new to the language. I say that because he writes Ruby as if he's writing some other language, and not idiomatic Ruby.

This:

  dirp = Dir.open(".")
  for f in dirp
    case f
    when /\.rb\z/
      print f, "\n"
    else
      # do not print
    end
  end
  dirp.close
Could be made much more Ruby-native (and simpler!) as:

  Dir.open('.').each do |f|
    puts f if f.match?(/\.rb\z/)
  end
My point isn't to play the "I know the language better than you, so nyah nyah" game, just to suggest that if the author likes Ruby as much as he says, he should learn it better.
7 comments

So the weirdest part is that the OP is literally just a cut and paste of a bunch of scripts found in the ruby distribution "samples" folder (that I had no idea even existed).

That pretty not great ruby wasn't written by the author -- it's actually included in a "sample" file with the ruby distro?

https://github.com/ruby/ruby/blob/ruby_3_1/sample/dir.rb

A file whose commit history shows... it's part of the very first commit recorded in git history, in 1998 by matz, the original author of ruby.

I have no idea what's going on in that "sample" folder, very weird.

The OP is simply regurgitating the weird "sample" folder. The "author" of the OP didn't write any of this code. According to git history... matz did?!?

I think the idioms develop over time. Or perhaps being samples, they were presented in a more language neutral way?

In any case, I wonder if the OP's motives were good or if this was just some SEO game... we have enough of the latter on the internet.

> A file whose commit history shows... it's part of the very first commit recorded in git history, in 1998 by matz, the original author of ruby.

So not necessarily written by Matz, but part of the body of work that eventually saw a `git init`, and early enough that much of the modern standard Ruby formatting was still emerging. Doesn't seem all that surprising to me in the context of when it was written.

This was written by matz some time between 1993 and 1994. It appeared in the very first preview release of ruby, version 0.49. The original tarball has the file modification timestamps:

    $ curl -s https://cache.ruby-lang.org/pub/ruby/1.0/ruby-0.49.tar.gz | tar -tvz | grep dir.rb
    -rw-r--r--  0 matz   root      127 Jun  3  1994 ruby/sample/dir.rb
Fun retrocomputing diversion: Initial Ruby development was done on Sony NEWS, the same type of workstation that hosted the earliest PlayStation development boards: https://en.wikipedia.org/wiki/Sony_NEWS
Hilarious origin story of Sony NEWS, how the engineers built a UNIX workstation they wanted, not what they were told to build.

> Sony's NEWS project leader, Toshitada Doi, originally wanted to develop a computer for business applications, but his engineers wanted to develop a replacement for minicomputers running Unix that they preferred to use.

> In the beginning, Doi's concept of the workstation was a device, which was essentially an extension of current [MIPS (Media Information Products and System) Business Group] projects. He saw it as consisting of "a 32-bit CPU developed in a short time with unrestricted applications." Basically, he thought of it as an OA computer.

> However, the engineers Doi selected for his team did not listen to what Doi told them to do. They wanted to develop a workstation that could replace the VAX Super Mini Computer developed by Digital Equipment Corp. (DEC). This was a computer that the engineers often fought with each other to use while at MIPS because of the limited number. They wanted to develop something they themselves could use for their own day to day work.

That file is very different with an added rewind and now case/when.

    dirp = Dir.open(".")
    dirp.rewind
    for f in dirp
      if (~/^\./ || ~/~$/ || ~/\.o/)
      else
        print(f, "\n")
      end
    end
    dirp.close

   if (~/^\./ || ~/~$/ || ~/\.o/)
ah, the perl heritage is strong here!
Then the reasoning for this weird code is that it's meant as a base to be extended. E.g. handling more variants of filenames? Anyways, maybe it's worth submitting a pull request with simpler code.
You're quite right -- the author of that code *was* very new to the language when he wrote this, but then again, so were we all. [0]

[0] https://github.com/ruby/ruby/commit/3db12e8b236ac8f88db8eb46...

Or even:

  puts Dir["*.rb"]
That snippet looks like Python/Lua/C with the for, case and close being used. Ruby is one of those languages that like Lisp/Scheme, Smalltalk or Haskell requires you to know what is going on as well as what is available to come up with a clean/simple solution. I think finding good Ruby resources that are up to date are few but I believe most of the stuff out there still works in recent versions.
> That snippet looks like Python/Lua/C with the for, case and close being used

Not really Python like at all - apart from the one line with for. Python doesn't have a case or when statement, or syntax level regex, doesn't open or close directories, and for files it would idiomatically would use the context manager for file access rather than closing it.

But it also doesn't look like any Ruby I've seen or written either :)

For the record, Python didn't have a case or when statement. It does now, recently added to version 3.10.
Doh, spending too long in Ruby lately - got some catching up to do.
>> I think finding good Ruby resources that are up to date are few...

I just finished a class that was taught with Ruby. It seems like an absolutely delightful language, but I could not find docs pertaining to several projects that I had conceptualized as my 'final project'. Microsoft Graph API has no docs available for Ruby.

Probably worth mentioning that each of those code snippets links out to a core sample in the ruby/ruby repository. There is a source link directly above the code you posted. https://github.com/ruby/ruby/blob/ruby_3_1/sample/dir.rb
I'm not familiar with Ruby, so I have a question: the first snippet has the .close method called while the second doesn't. Does the second example leak resources, or it's automatically closed after a GC in a finalizer, maybe? Does .each close the directory? Or, maybe, .close is a no-op in newer versions?
You’re quite right. OP’s rewrite contains a bug: it leaks one file descriptor per invocation. The correct version passes a block to `open` directly so that it’s automatically closed when the block is done executing. Maybe golfing down to be “idiomatic” isn’t always best :)

  Dir.open('.') do |dirp|
    dirp.each do |f|
      puts f if f.match?(/\.rb\z/)
    end
  end

https://ruby-doc.org/core-3.1.0/Dir.html#method-c-open

There are a few ruby stdlib classes like Tempfile that use the finalizer trick you mention to free resources on GC but Dir isn’t one of them. Here’s it’s implementation:

https://github.com/ruby/ruby/blob/1a24442193fe437e761e941d1a...

You couldn't be more wrong, and a simple Google search of the author was all you had to do lol. It's pretty clear here (given his background) that the author is writing in a style to make the code examples more accessible to a wider audience.
As a non-ruby developer, I find the initial example indeed much more readable.
That's why LOC doesn't mean anything and I find the latter way more readable except for the fact ruby puts "if" behind for a single liner which isn't really comfortable reading.