Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
September 12, 2021 05:09 am GMT

Ruby 3.1 Shorthand Hash Syntax First Impressions

It's the time of year again, and with it comes a bundle of new Ruby 3.1 features getting approved and merged ahead of the December release.

This series will be covering a few of the interesting ones I see going across the bug tracker. Have one you think is interesting? Send it my way on Twitter @keystonelemur or comment here.

Shorthand Hash Syntax - First Impressions

Now this, this is something I've wanted for a very long time. Shorthand Hash Syntax, also known as Punning in Javascript, is an incredibly useful feature that allows you to omit values where the variable name is the same as the key:

a = 1b = 2{ a:, b: }# => { a: 1, b: 2 }

In Javascript this would like like so:

const a = 1const b = 2{ a, b }

So you can see some of the resemblance between the two.

Commits and Tracker

You can find the relevant diff here and the bugtracker issue here.

Exploring the Testcases

Let's take a look into the specs from that diff (slightly abbreviated):

def test_value_omission  x = 1  y = 2  assert_equal({x: 1, y: 2}, {x:, y:})  assert_equal({one: 1, two: 2}, {one:, two:})endprivate def one = 1private def two = 2

Now as mentioned before, this allows value omission as specified in the first assertion:

x = 1y = 2assert_equal({x: 1, y: 2}, {x:, y:})

This is what I would expect the feature to do, and already opens up a lot of potential which I'll get into in a moment, but there's something else here in the second:

assert_equal({one: 1, two: 2}, {one:, two:})# ...private def one = 1private def two = 2

...it's also working on methods, which opens up a whole new realm of interesting potential. I'll be breaking these into two sections to address what I think the implications of each are.

Implications of Punning

Let's start with general implications, as I believe those alone are interesting enough to write on.

Pattern Matching

Consider with me pattern matching:

case { x: 1, y: 2 }# I do still wish `y` was captured here without right-hand assignmentin x:, y: ..10 => y then { x:, y: y + 1 }# ...end

This allows us to abbreviate the idea of leaving one value unchanged, and working with another value explicitly. In another case with a JSON response we might want to extract a few fields while changing one:

case responsein code: 200, body: { messages:, people: }  { messages:, people: people.map { Person.new(_1) } }in code: 400.., body: { error:, stacktrace: }  { error:, stacktrace: stacktrace.first(5) }# ...end

It allows us to be more succinct in what we're simply extracting and what we're transforming.

Note: I have not tried combining this with regular Hash syntax, but I assume this will work given the parse.y code. More experimentation needed.

Keyword Arguments

Keyword arguments in general are a huge value-add to Ruby for understandability and errors:

# (A tinge contrived, yes)def json_logger(level:, message:, limit: nil)  new_message = limit ? message.first(limit) : message  Logger.log({ level: level, message: new_message }.to_json)end

With one argument that's not too bad, but the biggest annoyance of keyword arguments is constantly doing this:

some_method(a: a, b: b, c: c, d: d + 4)

It feels repetitive and doesn't add extra value. Punning in JS elided this information into arguments which should be forwarded without transformation, and Ruby shorthand hash syntax does the same. The benefits of keyword arguments without all of the extra code:

some_method(a:, b:, c:, d: d + 4)

Now we can quickly see only d is being modified, allowing us to more clearly see the intent of the code, while also getting all of the benefits of keyword arguments around name checks, value checks, and more easily understood methods.

I see this being the highest value add.

Implications of Including Methods

This one is a bit more unusual, but I like the idea.

Configuration Hashes

There are a lot of cases where I have to assemble larger hashes of configuration. By putting parts of it into methods I've made it easier to manage:

def configuration  { a:, b:, c: }endprivate def a = {}private def b = {}private def c = {}

Those could be things like say logger configs, AWS keys, library configuration, and very interestingly (and I don't know if this would work) optional configuration cascades:

def configuration  {    **({ logger:, stack_limit:, tracing: } if logging.enabled?),    **({ shards:, rw:, clusters: } if db.sharded?),    # ...  }end

Of course those are theoretical and I would need to spend substantial time with this feature after nightly builds are out to be sure on this, but if it does work it opens the door for some very interesting cascading configuration styles in the future.

Wrap Up

This is a first impressions article on the shorthand hash syntax, and I expect as I have time to play with it I'll come up with some new ideas. Until then, I'll be watching the bug tracker for fun new features coming up soon.


Original Link: https://dev.to/baweaver/ruby-3-1-shorthand-hash-syntax-first-impressions-19op

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To