Crystal: feature request: add __END_LINE__ magic constant

Created on 16 Nov 2016  路  6Comments  路  Source: crystal-lang/crystal

this is allowed to implement, run spec for any line inside it, very handful for big tests;

  it "bla" do 
     ...
     ...
     ...
  end
feature accepted compiler

Most helpful comment

I've thought about this a bit, and maybe we can introduce a couple of entities inside macros. Right now we have @type, but we can add @def and @block. So for example:

Example with @def:

def foo
  # a.k.a. __method__
  {{@def.name.stringify}} # => "foo"
end 

foo

Example with @block:

def foo
  {{@block.line_number}} # => 7
  {{@block.end_line_number}} # => 9
  yield
end

foo do
  1
end

The compiler has this information, only that it doesn't exposes it. Of course this info is available at compile-time, not at runtime (info about block contents and locations is lost), so it makes sense to expose this at compile-time too, in macros. With this we can implement __method__, running specs between given line numbers (I thought about implementing this by making it be a macro, and then we have access to the block with &block, but I realized the same should be possible without using a macro definition), and probably some other nice things.

All 6 comments

I've thought about this a bit, and maybe we can introduce a couple of entities inside macros. Right now we have @type, but we can add @def and @block. So for example:

Example with @def:

def foo
  # a.k.a. __method__
  {{@def.name.stringify}} # => "foo"
end 

foo

Example with @block:

def foo
  {{@block.line_number}} # => 7
  {{@block.end_line_number}} # => 9
  yield
end

foo do
  1
end

The compiler has this information, only that it doesn't exposes it. Of course this info is available at compile-time, not at runtime (info about block contents and locations is lost), so it makes sense to expose this at compile-time too, in macros. With this we can implement __method__, running specs between given line numbers (I thought about implementing this by making it be a macro, and then we have access to the block with &block, but I realized the same should be possible without using a macro definition), and probably some other nice things.

I think the suggested solution would apply to my post Error: "undefined local variable or method '__method__'" at https://groups.google.com/d/msg/crystal-lang/wNcMzNw1bLg/Z27sz4VJAAAJ

Also #1582

After implementing @def and @block I remembered that spec's it captures the block, so there's no @block to access (because it's not a compile-time block that will be inlined) so to correctly implement it with what we have right now we'd have to turn it into a macro, which brings some more complications.

I think __END_LINE__ is a good simple solution. For calls without a block it will be the same as __LINE__, but with a block it will be the last line of the block.

I'll probably add @def too, but I won't add @block because it doesn't seem to be very useful now, and can bring some confusion inside macros compared to &block and yield.

After the next version is released I will add this feature to spec.

I saw how rspec does it and it seems to only do it for it blocks. For example, if I specify a line that is in the middle of a describe block but in no particular it block then I think it runs the closest previous spec. Is that expected behaviour? In any case I think the most useful case is when you are debugging a particular spec but don't want to remember its first line.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

malte-v picture malte-v  路  77Comments

asterite picture asterite  路  70Comments

asterite picture asterite  路  60Comments

HCLarsen picture HCLarsen  路  162Comments

benoist picture benoist  路  59Comments