3 ms·
As someone who comes from strict languages (the more strict, the better) Ruby blocks are... not fun. I've seen them used in situations where they are used like
by OptionOfT 1y ago
As someone who comes from strict languages (the more strict, the better) Ruby blocks are... not fun.
I've seen them used in situations where they are used like a callback, but due to the nature of how you write them, you have no clue whether the variable you're referring to is a local or a global one.
This makes debugging incredibly hard.
- deleted 1y ago[deleted]
- inopinatus 1y agoRuby isn’t strict, no, but that’s by the by, because this doesn’t sound like a problem with blocks or how you write them. It sounds more like a problem with evals i.e. some library or framework misusing them. Blocks are closures and they straightforwardly bind variables and resolve constants/instance variables from the context of their instantiation, and resolve methods similarly because self within the block is from instantiation, when we call them normally with yield or Proc#call. Same goes for implicit contexts used for definition, if your block does a bit of metaprogramming. If someone plays silly buggers and invokes them under instance_eval or class_exec etc that fiddle with self or definition contexts then some of this goes out the window, but those are special-purpose methods that come papered with red flags. This is typically seen in poorly designed DSLs that are trying too hard to pretend they’re not actually Ruby. If memory serves, the Chef DSL was a prime example in this regard. If the language was stricter, then sure, this wouldn’t be possible. But debugging these cases isn’t super hard either once you know the limited range of culprits, and the fix is always the same: place values in local stack variables to rely on them in a closure. Using blocks for callbacks is fine. Don’t make assumptions about the semantics of flow control statements that other languages may have imposed on you, i.e. use next and break for explicit block results and local exit instead of return, and don’t eval them.