Even something as basic as "if" is done with message passing and blocks in Smalltalk.

There's a method named "ifTrue:ifFalse:" in Smalltalk (with each ":" expecting an argument, in this case, a block).

You can also chain messages and make phrases: `anObject aMethod; anotherMethod; yourself.`

The Ruby equivalent has repetition: `an_object.a_method; an_object.another_method; an_object`

or requires a block: `an_object.tap { _1.a_method; _1.another_method}` (and we usually use newlines instead of ";")

I have found that chaining things in Smalltalk get immensely painful after just a couple elements. Unlike most other languages, I find myself reaching for silly little var names for lots of different things I would normally just let flow.

Really? To each their own, but honestly, I found smalltalks way of chaining things to be one of the most elegant parts of what is admittedly a syntactically-simple language (the old "fits on a postcard" thing).

With Smalltalk, with regard to return values or chaining, you get to have your cake and eat it too.

Your methods CAN return sensible values which don't necessarily have to be the original object. BUT, if you just want to chain a bunch of sends TO A PARTICULAR OBJECT, you can use ;, and chain the sends together without requiring that each intermediate method returns the original object.

That combined with the fact that chaining sends requires no special syntax. You just write them out as a single sentence (that's what it feels like), and you can format it across multiple lines however you wish. There's no syntax requirements getting in the way.

Just finish the whole thing with a dot. Again, just like a regular sentence.

And if you find precedence or readibility becoming confusing, then just put stuff in parens to make certain portions clearer. There's absolutely no harm in doing do, even if in your particular use case the normal precedence rules would have sufficed anyway.

    Smalltalk
      complex method chaining;
      again (as mentioned previously)
      reads like English.

In Ruby, methods called mainly for side effects rather than return value conventionally return the object itself, and so can be chanined by:

  an_object.a_method.another_method
but, sure, it's less elegant (or at least less terse) than Smalltalk for the specific case of chaining invocations of methods with meaningful return values which are called for their side effects while discarding the return values.