Hacker News new | ask | show | jobs
by WJW 3104 days ago
I started using Ruby only in April this year due to starting at a new job. Having used and/or dabbled in C, Java, Python and Haskell before (amongst others), I find it super interesting to see how Ruby manages to take some interesting parts from each and manages to integrate it into a very pleasant programming experience. Also the rspec testing library is nothing short of magic, none of the compiled languages have anything that even comes close IMO.

For the cases where you have a tight loop taking up 99% of the actual CPU time it is also relatively easy to hook in C or Rust or whatever. Also, sometimes you hit hardware performance limits regardless of the language you use. We have some streaming download servers written for 99% in Ruby using the libCurl bindings that and they easily manage to fill up the 5 Gbps pipe* per server that AWS gives us.

* You can get 20 Gbps for some instances, but only to other instances in the same group. The biggest to the 'outside' seems to be 5 Gbps.

4 comments

While rspec is indeed nice, I don't get why most projects don't use minitest more. Minitest ships with the Ruby standard library and I much prefer the assert syntax over the rspec DSL.

Rails also uses minitest with fixtures by default, I migrated to it recently and I really like the simplicity.

minitest also provides a spec-style DSL. Rspec is a hog, minitest is much, much cleaner and leaner, even if you use the DSL.
I'd be very interested to know what you mean by "nothing short of magic". I've had a quick look at the rspec documentation and as a Python dev this looks very similar to what's in the Python standard library. Would that be considered magic as well or does rspec have some cool features that I have missed?
Note how I said compiled languages, I expect Python to have some very similar capabilities. :) But as an example, take the cleanness of the following mock:

  allow_any_instance_of(Set).to receive(:member?).and_return(true)
  <rest of test code>
Contrast this for example with testing IO monad code in Haskell, where the best practice is to define a new monad 'underneath' your original monad stack, rewrite all your functions signatures to have a type constraint (of your new MonadIO type) and then switch out functions for their mocked equivalent as required by the test. Rspec can do the same switching out on any object or class, without any code required outside the test code. (Although as far as "handle with care" goes, monkeypatching the 'send' method has to score pretty high)
rspec’s internal DSL is based on Ruby’s multi-line anonymous functions. I don’t know how you achieve a similar design in Python where you don’t have those in the same way. How do you write the equivalent of ‘it ‘does something’ do ... end’ in Python syntax?
This seems a good starting point https://stackoverflow.com/questions/37334668/is-there-a-pyth...

TLDR: not as nice as RSpec but close.

> not as nice as RSpec

Right, well that probably answers the question about what they thought the magic is.

Not too familiar with Rspec but I know Groovy (a compiled language) has testing frameworks like Spock that I believe are based on Rspec.
> Groovy (a compiled language)

Because of its use in scripting on the JVM(e.g. glue code and Gradle builds), Apache Groovy files are usually stored in the file system as text. Each time they're run, they are "compiled" into JVM bytecode. Although you can get pre-compiled .class and .jar files for Groovy, it's not common for people to build large systems with it.

Cool which libcurl bindings are you using?
Patron, from here: https://github.com/toland/patron. We use it in combination with our (open source) FastSend gem to keep the streamed data away from the Ruby garbage collector, since it gets a bit emotional if it has to clear out hundreds of MBs every second. If you're interested why we chose this architecture instead of just redirecting to S3, our lead engineer gave a talk about the reasoning behind this structure. You can find the slides at https://speakerdeck.com/julik/streaming-large-files-with-rub....
You can fill GB/s with net/http. You could do so easily with 1.9. The GC shouldn't be a problem unless your object graph is very complicated.