Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow visibility modifiers without a target (similar to Ruby) #6104

Closed
wants to merge 1 commit into from

Conversation

asterite
Copy link
Member

With this you can do:

class Foo
  def foo # public by default
  end

  private # everything that follows is private

  def bar
  end
end

I personally miss this feature the times I use Crystal. It might have been a whim back then. The reason is that if you have lots of methods under private you can't immediately see if a method is private or not. But I don't think that's a big deal. This way (Ruby's way) is nice because you have to type a lot less, so it's more DRY. It's also nice to put public API at the top and all private/protected API at the bottom.

Side note about my gloomy comments in Reddit and other places: by now you might have realized that I have lots of up and downs with Crystal (at least the guys at Manas already know this :-P). So just ignore me when I'm like that. I think I'll always come and go, because I like Crystal to the point that I'll probably never abandon it. I have way much less time than I used to have when we started coding Crystal (in fact I can't really understand how we made it happen, or how we could spend so much free time on it), so I'll do what I can when I have time.

@@ -82,7 +82,8 @@ describe "Parser" do
it_parses %(:"\\\\foo"), "\\foo".symbol
it_parses %(:"\\\"foo"), "\"foo".symbol
it_parses %(:"\\\"foo\\\""), "\"foo\"".symbol
it_parses %(:"\\a\\b\\n\\r\\t\\v\\f\\e"), "\a\b\n\r\t\v\f\e".symbol
# TODO: uncomment after 0.24.2
# it_parses %(:"\\a\\b\\n\\r\\t\\v\\f\\e"), "\a\b\n\r\t\v\f\e".symbol
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This spec is failing for me, so I commented it. It's because \a was introduced, but it can't be used yet.

@RX14
Copy link
Contributor

RX14 commented May 19, 2018

I actually don't like this change for the reason you pointed out: it's hard to see whats private and whats not.

I think that it's not a big deal to put private before each def, I just don't find it that common of a thing to do. I like the way that method declarations are self-contained in that you can reason about one by itself. This is a minor thing, but it breaks that for avoiding such a small bit of extra typing and I definitely don't think it's worth it.

@j8r
Copy link
Contributor

j8r commented May 19, 2018

I agree with @RX14 on this, we can really easilly miss this little keyword.

I've a (false?) good another idea, why not having a block syntax to have an indentation like:

class Foo
  def foo # public by default
  end

  private # everything that follows is private
    def bar
    end
  end

end

But this adds another indentation.

@asterite
Copy link
Member Author

Yeah, we could do that with:

private begin
  def bar
  end
end

but the indentation it creates is ugly... I think Ruby's been fine in the last 25 years with that, and many wanted it for a long time.

@ysbaddaden
Copy link
Contributor

We can still have private def for single private/protected methods? Then I'm fine with this.

@sdogruyol
Copy link
Member

Let's not copy Ruby this time.
When writing Ruby, I always miss the Crystal way of defining private methods. It's explicit and also impossible to miss the private keyword no matter how big the file is.

@Sija
Copy link
Contributor

Sija commented May 20, 2018

@sdogruyol That's not just Ruby, C#/C++ or Java does the same for instance.

@jwoertink
Copy link
Contributor

Ruby lets you pass a symbol to those keywords so you can do private :foo, and since all method definition return a symbol, doing private def foo; end in ruby is allowed. So, crystal already copies ruby in that sense.

I actually didn't even notice this wasn't possible in crystal since I've enjoyed being more explicit. If your only basis is that this makes it more DRY, and less typing, an alternative could also be elixir style. Using something likedefp foo, but that feels more like an alias, and we don't use alias in crystal.

@asterite
Copy link
Member Author

I guess it might not be good after all.

@asterite asterite closed this May 22, 2018
@Sija
Copy link
Contributor

Sija commented May 22, 2018

@asterite maybe let's vote on that?

@j8r
Copy link
Contributor

j8r commented May 22, 2018

I've another bad idea (sorry again).
For now for methods we have:

def foo
  raise "error"
rescue
  puts "rescued"
ensure
  puts "ensured"
end

The idea is to also apply this concept to classes, by just removing one indentation to the original implementation:

class Foo
  def is_public
  end
protected
  def is_protected
  end
private
  def is_private
  end
end

It's clearer because this forces to group similarly scoped methods together, and the key word in on the same line as class, not the one of defs.

@straight-shoota
Copy link
Member

Just keep it as it is: private def and protected def. There is nothing bad about that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants