Live data from Hacker News

Gem adds support for creating state machines for attributes on any Ruby class

github.com

41–50 of 50 posts

Re: Gem adds support for creating state machines for attributes on any Ruby class

#41
post #27

Earlier quoted context omitted.

Positionally-significant colons is more nightmarish than significant whitespace. Speaking as a critic of significant whitespace. Put them at the front and make them mean something, or put them at the back and make them mean something, Making both places mean something entirely different, or even allowing both as an allowable syntax, is horrible for readability.

They mean "symbol" either way, except when trailing ":" also means they're a key. I'd be inclined to agree it's a wart, but not that it affects readability to any noticeable amount. In this case, though, the DSL looks just awful to me.

To expand on this:

Contrary to constants which are fixed+ references to values, symbols are pure values: they're like integers but with a textual name. Explicitly they are not strings.

They used to be very useful because a symbol takes little memory and comparing two symbols means comparing two integers; it's a bit like `#define FOO 42` in C, except `42` is automatically picked up and you don't care what the value actually is.

They are less useful today because there have been a lot of improvements e.g with frozen string literals (which are now stored only once and thus can be compared much more efficiently). Still that has a lot to do as to why they're used for kwargs and hash keys and method names and a ton of other stuff, where without symbols you'd have a ton of the same strings showing up over and over, so instantiated and compared.

The hash syntax used to be only arrow but it was so common to do `:foo => "bar"` that at some point Ruby (1.9) introduced `foo: "bar"`, which makes writing hashes look like JSON/YAML and kwargs more like other languages like Python. This does make it a bit surprising because suddenly there's a symbol that is not prefixed with `:` but it also makes things a ton more readable in many cases.

I do use the "new hash syntax" liberally, but also still use arrow hashes a lot because it all depends on the way things are written around and sometimes one is more readable than the other.

For example in general I don't like writing rake task target dependencies or Rails routes with the new syntax, the arrow one makes more sense to me. Or when one can have mixed keys that can be symbols or some other types, I find it more readable to have a consistent hash syntax, so I go to the old arrow one.

+ well, although frowned upon, constants can be reassigned, they're essentially just some variables albeit with a different scope and resolution system.

Re: Gem adds support for creating state machines for attributes on any Ruby class

#42
post #31

Earlier quoted context omitted.

Both of these gems just feel unreasonable verbose to me. E.g. why "transitions from: :somestate, to: :otherstate" vs just "transition :somestate => : otherstate"? A lot of the syntax of these feels over-engineered, or like someone has just read a Smalltalk introduction and is overdoing keyword arguments to emulate it. If I'm going to use a DSL to define a state machine, it better be a lot terser and/or clearer than a…

I worked on a state machine framework in another language, and have definitely have found less terse to be pretty good. Typing a few extra characters isn't that bad, especially if it makes some awful bit of evented code easier for someone to understand. Of the things available open source, I think P-lang is pretty cool: https://github.com/p-org/P/blob/master/Tutorial/1_ClientServ...

There are thresholds in both directions, and I find the state_machines examples go way too far in the direction of verbosity to the point where it makes it harder rather than easier to see what is going on.

I'd argue the same for your P-lang example.

The state transitions in your example are trivial to the point where a "framework" is entirely unnecessary, but even then they are hidden inside the implementation details in a way that forced me to read the implementation to realise that they're trivial.

If I have a state machine that is complex enough that I want a "framework" to simplify things, my first requirement will be that it makes clear the state transitions and criteria separate from the implementation of them. Both the state_machines gem and the other Ruby gem mentioned in this thread have examples that in my opinion does a far better job at separating that.

Re: Gem adds support for creating state machines for attributes on any Ruby class

#43
post #12

Earlier quoted context omitted.

Ruby uses symbols (strings prefixed with a semicolon) very liberally. It’s just a value literal. Ive never met anyone who writes Ruby that has an issue with the readability of it.

Selection bias

Would disagree. I write in other languages and I find things tough to read. There are things about ruby I find tough to read (like `unless`) and know many other people who agree.

Symbols work just fine in practice.

Re: Gem adds support for creating state machines for attributes on any Ruby class

#44
post #29

I'm not sure why this is interesting enough to post. It's an old gem, and the DSL seems awfully verbose to me for how little it does. I love Ruby, but I wouldn't want to write Ruby like this...

My first thought when reading the examples is I'd rather just implement myself manually.

Re: Gem adds support for creating state machines for attributes on any Ruby class

#45
post #26
post #6

Earlier quoted context omitted.

Wait, is :state a keyword or an instance attribute? Using the same syntax for both seems really confusing.

Ruby doesn't have "instance attributes". Instance variables are prefixed with "@". Anything prefixed by ":" is a symbol. In some contexts we use symbols to refer to methods by name. Anything you might thing is an "attribute" is likely a method. E.g. on some_object.name, name is always a method. You might be confused because e.g. "attr_reader" takes symbol arguments, because it's just another method. E.g. "attr_reader…

So it's just a symbol, but in this context it will be used to look up the "state" method? Not unlike how symbols are sometimes used as "designators" of various things in Lisp?

Re: Gem adds support for creating state machines for attributes on any Ruby class

#46
post #12

Earlier quoted context omitted.

Positionally-significant colons is more nightmarish than significant whitespace. Speaking as a critic of significant whitespace. Put them at the front and make them mean something, or put them at the back and make them mean something, Making both places mean something entirely different, or even allowing both as an allowable syntax, is horrible for readability.

Ruby uses symbols (strings prefixed with a semicolon) very liberally. It’s just a value literal. Ive never met anyone who writes Ruby that has an issue with the readability of it.

https://wikipedia.org/wiki/Stockholm_syndrome

Re: Gem adds support for creating state machines for attributes on any Ruby class

#47
post #2

I think Ruby is OK enough, but what is this? state_machine :state, initial: :parked do I think in their zeal to "golf" the language, they forgot to actually keep it readable

Readability is one of Ruby's strengths. Most custom DSLs I've encountered are easy to understand. Arguably meta programing makes it harder but the language allows you to strike the balance that suits you.

good joke

Re: Gem adds support for creating state machines for attributes on any Ruby class

#48
post #8

Earlier quoted context omitted.

This is idiomatic Ruby syntax, and anyone familiar with the language knows what that code does

This is kind of an absurd statement, given how prevalent custom DSLs are in Ruby (and in this example). No amount of familiarity with the Ruby language can tell me what this means: event :ignite do transition stalled: same, parked: :idling end You have to be familiar with the DSL, not Ruby.

It's generally good practice to read a library's documentation to understand how to use it - there's not really a short cut to that, regardless of the language.

As for the syntax, you know that `event` is a method, passed the param `:ignite` and a block, and in that block, you call the method `transition` with kwargs `{stalled: same, parked: :idling}`, and `same` is another method call.

Re: Gem adds support for creating state machines for attributes on any Ruby class

#49
post #46
post #12

Earlier quoted context omitted.

Ruby uses symbols (strings prefixed with a semicolon) very liberally. It’s just a value literal. Ive never met anyone who writes Ruby that has an issue with the readability of it.

https://wikipedia.org/wiki/Stockholm_syndrome

Is it stockholm syndrome if I leave ruby and years later still wish I had symbols in other languages?

Re: Gem adds support for creating state machines for attributes on any Ruby class

#50
post #48

Earlier quoted context omitted.

This is kind of an absurd statement, given how prevalent custom DSLs are in Ruby (and in this example). No amount of familiarity with the Ruby language can tell me what this means: event :ignite do transition stalled: same, parked: :idling end You have to be familiar with the DSL, not Ruby.

It's generally good practice to read a library's documentation to understand how to use it - there's not really a short cut to that, regardless of the language. As for the syntax, you know that `event` is a method, passed the param `:ignite` and a block, and in that block, you call the method `transition` with kwargs `{stalled: same, parked: :idling}`, and `same` is another method call.

Indeed I know all of this. But in terms of "what this code does," the information that a method is passed a block that calls another method is not particularly interesting. The major problem I have with this sort of DSL is it encourages people to infer what it does based on what the ad hoc method names make it sound like this is intended to do. So many of these custom DSLs are documented by example rather than by any decent specification. The attitude that these clever little grammars make it so you can "just read it and it's obvious" is, in my opinion, sloppiness in code comprehension taken to an extreme.
Post reply on HN