1

So, for hashes in Ruby you can use hashrockets like this:

corned_beef = {
    :ingredient1 => "beef",
    :ingredient2 => "potatoes"
}

or the more concise json-ish style.

corned_beef = {
    ingredient1: "beef",
    ingredient2: "potatoes"
}

Is there a json-ish styled way to catch Ruby exceptions? The normal way is this:

begin
    # ...blah blah...
rescue ActiveRecord::RecordNotFound => e
    logger.debug { "Where's da beef?" }
rescue => e
    logger.debug { "#{e.message}\nBacktrace Begin:\n #
        {e.backtrace.join("\n")}" }
else
    # ...blah blah...
end

I've started to hate seeing hashrockets in my code, even for this. Someone please educated me.

EDIT: For some reason, this has attracted comments from the kind of people who have code-religious arrogant condescending judgement. This is a forum for questions, if you don't like the question, kindly close your window. Ruby was optimized for programmer happiness. My question is seeking what I deem cleaner sexier code. What is not wanted is an expression of lots of opinions that do nothing toward helping achieve an answer. I am a good programmer with legacy code that has been in production serving billions and is probably older than most of you. Please stop shoveling pointless opinions if it doesn't answer the question. So far, it doesn't look like what I'm seeking exists. That's fine.

Michael K Madison
  • 2,242
  • 3
  • 21
  • 35
  • 4
    Nitpicking: "JSON-style" would actually be `"ingredient1": "beef"` since all keys in JSON objects are quoted strings. And if you never use hashrockets then you're artificially limiting how you use hashes in Ruby: hash keys can be almost anything, not just symbols. That said, I'm not aware of any *Javascript-object-literal*-style syntax for `rescue` in Ruby. – mu is too short Dec 31 '17 at 03:29
  • Yes, it is nitpicking and somewhat irrelevant to my question. I like the shortest cleanest way. Yes, I can use quoted strings, but rarely do unless it's forced (for example using Sidekiq -- even then there are add-ons that allow hashes with indifferent access) but why should I, its one more character to type per attribute and annoying. I'll edit to json-ish. – Michael K Madison Dec 31 '17 at 07:58
  • How is that a hashrocket, not just a rocket? Does it have anything to do with a hash? – Stefan Pochmann Dec 31 '17 at 13:39
  • 1
    @MichaelKMadison you realize that "indifferent access hashes" actually use `String` keys instead of `Symbol` keys correct? [`ActiveSupport::HashWithIndifferentAccess`](https://github.com/rails/rails/blob/master/activesupport/lib/active_support/hash_with_indifferent_access.rb#L284) Also "hash rocket" syntax is needed for other implementations too, such as conversion of a variable to a literal hash key (e.g `object.each {|k,v| {k => v}}`) because `{k: v}` would have a key of `:k` (Symbol) rather than the value of `k` – engineersmnky Jan 02 '18 at 14:56
  • @engineersmnky Thanks for your comment. It doesn't necessarily help at all though. Indifferent access exists to allow people to write their code as they see fit in the spirit of programmer happiness. The implementation minutia doesn't really matter. – Michael K Madison Jan 02 '18 at 18:53
  • @MichaelKMadison thank you for you comment although you may feel free to disregard the first portion of my comment which you seem to be regarding as "arrogant" and pugnacious the second part of my comment still holds water and the purpose was simply to show that "hash rockets" are a syntactical necessity in the ruby programming language and should not be seen as ugly or second class – engineersmnky Jan 02 '18 at 19:12
  • @engineersdmnky In general, I feel most people on stack overflow behave in a way that is less than efficient. The first wave is usually the "chip shots" -- i.e. completely meaningless things pointed out that are technically true. Like "hey you misspelled this" or "technically this is... blah blah blah" but completely irrelevant to the question. If you already understand the language used, well that's the point of communication. If you already know you're nitpicking, have the discipline to just stop and ask if your response is net positive. – Michael K Madison Jan 08 '18 at 18:49
  • @engineersmnky The third wave of annoying responses is the category you fall into. You gave you something somewhat arcane that you believe is true yet still irrelevant to answering the question. The form I detest the most, is a comment or answer that falls in the semi religious scope of invalidation "what you're asking for, you shouldn't ask for, let me tell you why." Instead of answering my question, you commented that I should not feel the way I feel about hashrockets... oh excuse me rockets, b/c God forbid you still understand what I mean but it's not in reference to hashes. – Michael K Madison Jan 08 '18 at 18:54
  • that's right... I'm waiting for someone to ask what was the second wave :) complete waste. – Michael K Madison Jan 08 '18 at 18:56
  • 1
    @MichaelKMadison there is nothing arcane about implementation when an indifferent `Hash` is multitudes slower due to the transformation overhead. (Fact not belief) and I mentioned nothing about "rockets" and I simply quoted "hash rocket" because it is a terminology of the `=>` notation. It seems fairly hypocritical of you to consider others "arrogant" and "condescending" and then turn around and act in such an elitist manner. All I was saying is this syntax is a core component of the language and a requirement in many cases. I wish you all the best in your pursuit of a sexier implementation. – engineersmnky Jan 08 '18 at 19:05
  • sheesh, let's continue arguing and further dilute actual content. – Michael K Madison Jan 08 '18 at 19:08

2 Answers2

3

If you absolutely want to get rid of it, you can fall back to some of Ruby's Global Variables, specifically

$!
The exception information message set by 'raise'.
$@
Array of backtrace of the last exception thrown.

begin
  raise ArgumentError, 'Your argument is invalid'
rescue ArgumentError
  puts "#{$!.message}\nBacktrace Begin:\n#{$@.join("\n")}"
  # or
  puts "#{$!.message}\nBacktrace Begin:\n#{$!.backtrace.join("\n")}"
end

I've never used any of the globals in an any real applications, so not sure what type of things you might want to watch out for (if multiple threads throwing different errors simultaneously* might be an issue, for example).

Simple Lime
  • 10,790
  • 2
  • 17
  • 32
  • 2
    While this is interesting to know, using this technique would be a huge disservice to the code base, teammates, and ultimately oneself. Conventions don't always have to be followed, but there should be a compelling reason for not doing so. Having a subjective revulsion to a hashrocket is not, IMO, such a reason. – Keith Bennett Jan 01 '18 at 02:21
  • 1
    The code at https://gist.github.com/keithrbennett/93571e3aff74ca2cf1343d905e8a20ae illustrates that $! is a threadlocal and not a global variable. – Keith Bennett Jan 01 '18 at 04:53
  • @KeithBennett by its designation `$` it is technically a global as shown in the post due to its declaration in ruby globals. It just happens to be a thread global allowing it to retain thread safe values. Its assignment is also block temporary [Examples of Both](https://repl.it/@engineersmnky/JuicyFarawayAmericanriverotter). Explanatory outline of "globals" from [Idiosyncratic Ruby](https://idiosyncratic-ruby.com/9-globalization.html) – engineersmnky Jan 02 '18 at 15:44
  • Additionally this [Great Slideshow](http://avdi.org/talks/rockymtnruby-2011/things-you-didnt-know-about-exceptions.html) on other exceptional things an provides one of the only reasonable examples I have ever seen for using `$!` – engineersmnky Jan 02 '18 at 15:44
  • Stating something in the documentation is one thing; observing its actual behavior is another. It is, as you say, documented in the list of globals, but (unless my observation is flawed) there is a separate variable in memory for each thread. So in the usual sense of the word 'global', that is 1 value per VM, it is *not* global. I believe it to be an unfortunate omission from the documentation. The regexp `$` variables are also thread-specific. – Keith Bennett Jan 02 '18 at 15:53
  • 1
    @KeithBennett I agree it is slightly misleading in the term "global" (which apparently to ruby means predefined and always available). That being said [`english.rb`](https://github.com/ruby/ruby/blob/trunk/lib/English.rb) allows for a bit more "explanatory" version of the proposed answer using `$ERROR_INFO` as an alias for `$!` which I think lends greatly to the readability. – engineersmnky Jan 02 '18 at 16:04
2

No, AFAIK this is the syntax required for creating a reference to the caught exception.

Keith Bennett
  • 4,722
  • 1
  • 25
  • 35