Crystal: Less Pollution through `using` Declaration

Created on 16 Sep 2016  路  5Comments  路  Source: crystal-lang/crystal

Less Pollution through using Declaration

Don't we all want to do more to help our environment? Of course! So, why not a using keyword to "open namespaces" in specific scopes - _without including them_ in the current module/namespace nor adding anything to their modules.
This would be a great way to limit DSL's and other things to tighter regions of code.

Something like:

module Foo
  extend self
  def x() 2; end
  def y() 2; end
end

module Bar
  extend self
  def x() 1; end
  def u() 47; end
end

def y() 3; end
def z() 3; end

# p x  # error!
p y  # => 3
p z  # => 3

using Foo
  p x  # => 2
  p y  # => 2
  p z  # => 3

  using Bar
    p x  # => 1
    p y  # => 2
    p z  # => 3
  end
end

using Foo, Bar
  def u() x + y + z; end

  u  # => 47 or 6? (see a/b/c)
end

p u  # => 6

With the last "namespace" in the list as the preceding in lookup. The currently active namespace could be included too, to clearly define its order as lookup in the scope, _iff_ option (a) below should be favoured (but that is probably just confusing).

Precedence alternatives

  • a) Def u above is defined in namespace :: but it's definition is under using Foo, Bar _lookup scope_. u is also defined in Bar, which is "included later" in the scope: thus precedes in the using scope over current actual namespace's definition.
  • b) Or? It's deemed more likely that anything _defined_ in a scope, after the initial using header is considered "on top" of the uses and hence first choice.
  • c) Or, finally; the current namespace is always considered as first choice, and then those listed in using in order (similar to include). Then one can never override anything in the current namespace within a using scope. This is arguably the most expected one.

Most helpful comment

I'd prefer begin/using .../end (or any existing scope, doesn't have to be a begin) over using .../end.
Reasons: familiarity from other languages; less trouble for text editors.

All 5 comments

Cool trick! But doesn't allow simply listing a bunch of modules nor defining types and methods which I see as a crucial part.

I'd prefer begin/using .../end (or any existing scope, doesn't have to be a begin) over using .../end.
Reasons: familiarity from other languages; less trouble for text editors.

Isn't this achievable with with something yield ?

@ysbaddaden , see https://github.com/crystal-lang/crystal/issues/3319#issuecomment-247660123 - I don't think I can define types and methods then? Or am I missing something.

@BlaXpirit - that could work too, as long as the uses are only available within the begin .. end scope they're declared I'm happy :-)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pbrusco picture pbrusco  路  3Comments

ArthurZ picture ArthurZ  路  3Comments

oprypin picture oprypin  路  3Comments

will picture will  路  3Comments

asterite picture asterite  路  3Comments