top | item 38488389

(no title)

progne | 2 years ago

Just 12 years full time with Ruby here, I'm a noob. But when I see that I could replace

  def initialize(text)
    @text = text
  end

  def inspect
    "#<#{self.class} #{text}>"
  end

  def ==(other)
    other.is_a?(Word) && text == other.text
  end
with

  def initialize(text) = @text = text
  def inspect = "#<#{self.class} #{text}>"
  def ==(other) = other.is_a?(Word) && text == other.text
I start drooling a little. That's 3 lines to replace 11. We have a soft limit on class length of 100 lines, and I like the extra conciseness this allows.

You can also do it like

  define_method(:inspect) { |text| "#<#{self.class} #{text}>" }
and we do that in some places, but that extra verbosity makes for more lines.

discuss

order

stouset|2 years ago

Unnecessarily cramming more density into one line to avoid soft limits seems like a poor tradeoff.

Ask any typesetter. Blank space used well gives text breathing room, making it easier to parse visually.

In the former example, it is extremely easy to pick out what each method name is and a decent idea of what it does at a glance. In the latter, I have to read to even see the method names.

kazinator|2 years ago

Ask a typesetter? No thank you.

What is a typesetter? Someone or something which takes tree-structured sentences, cranks them into a linear sequence of words, which is arbitrarily chopped into a rectangular form, with the goal being that the rectangle appear evenly gray from a distance. Sometimes ugly hyphens are inserted into the middle of tokens.

Pxtl|2 years ago

I feel like I'd still want the body on its own line from the signature definition just for readability. And with the parser problems described in TFA, I'd say that parens should be mandatory coding-style enforced by linter.

  def initialize(text)
    = (@text = text)
  def inspect 
    = ("#<#{self.class} #{text}>")
  def ==(other) 
    = (other.is_a?(Word) && text == other.text)
seems like a good compromise.

edit: this is similar to our standard when writing one-liner methods in C#. A bit noisier because of types and visibility, but still pretty concise, imho.

  public void Initialize(string text)
    => Text = text; 
  // I actually hate the above a bit because "=>" 
  // originally implied functional/no-side-effects 
  // in C#, but the world moves on.

  public string Inspect()
    => $"{this.GetType().Name} {text}>";

  public static bool operator== (Word a, Word b)
    => a.Text == b.Text;

vidarh|2 years ago

Personally I'd never let your first example through a code review. If you're going to break it up, use end. Where the one line format makes sense is when the body is trivial and often when there are multiple related methods that can be lined up to highlight their similarities and differences in the single line format.

kazinator|2 years ago

TXR Lisp:

  1> (defstruct (word text) ()
       text
       (:method print (me stream pretty-p) (put-string `#<@(typeof me) @{me.text}>` stream))
       (:method equal (me) me.text))
  #<struct-type word>
  2> (new (word "abc"))
  #<word abc>
  3> (equal *2 "abc")
  t
You wouldn't define a print method for a struct like this, because it's counterproductive. You're throwing away print-read consistency in exchange for no benefit.

I usually define print methods for complex structures with many slots, that are not expected to be externalized. Particularly if they are linked in a graph structure, where (even if you have the circular printing turned on to handle the cycles) the prints get large. You know, you wanted to just print the banana, but it was pointing to a gorilla, and basically a dump of the whole jungle ensued.

vidarh|2 years ago

You wouldn't define an `inspect` method for this simple example in Ruby either, because Ruby provides a default inspect that'd do just fine in this example. The exact same tradeoff for when to define inspect as for when you'd define print methods exist. In other words, that wasn't the point.

sdf4j|2 years ago

> We have a soft limit on class length of 100 lines, and I like the extra conciseness this allows

I'd recommend your team to stop code-golfing... Even better: with this new syntax you MUST reduce the soft limit to around 50 lines per class, right?

progne|2 years ago

I agree that it shouldn't be used for anything complex, even if it reduces to one line. But I do like it for simple things. Maybe it's staring at very similar code all day, but such short statements read fluently for me.

And even if an extra line of separation is used, it's still 6 lines instead of 11.

mschuster91|2 years ago

> We have a soft limit on class length of 100 lines, and I like the extra conciseness this allows.

The "compact" line format is something that is very information dense and really really hard to parse for a human's eye, compared to the clearly visually structured prior format.

Personally, if I'd see something like that outside of a code golf tournament, I'd run because that kind of code density means that at least one of the developer(s) believes themselves to be some kind of code wizard who loves Matrix-style display, and it means that new developers have a very steep learning curve ahead of them.

kbenson|2 years ago

What can be good, but requires discipline, is to replace some of the syntax that's no longer needed with a comment to help explain the what and why and goal. You reduce or eliminate the line savings, but overall may increase the information and understanding of intent.

I do this commonly in the Perl I write. If I'm using a complex set of maps and greps to reorganize a structure, doing that inline can be useful to the developer because it can match mental state, but the later reader may be somewhat lost when seeing it depending on how much of the data state they've internalized. A nice comment to explain the intent is useful, and when you're already saving space by eliding syntax, keep a good ratio of action to code on the screen (which is really what we're optimizing for here most times anyway, right?)

jlarocco|2 years ago

Seems counter productive to me.

The first snippet is much easier to read, and using this technique to get around your 100 line rules seems to be missing the point of the rule - or purposely subverting it.