Prohibiting overloading of a method

I want to warn the user when they have overloaded a method they shouldn’t, because doing so, at least without calling super, would disable facilities they expect to use. Is there a way to do this in a macro?

Replying to my own question, I think I got it:

abstract class A
  macro inherited
    macro method_added(method)
      \{% if method.name == "one" %}
         \{% puts method.name %}
         \{% raise %Q(Don't override method "A#one", use X and Y instead.) %}
      \{% end %}
    end
  end


  def one
    1
  end
end

class B < A
  def one
    2
  end
end

2 Likes

I’m asking just for curiosity’s sake, but is there another way to accomplish this, without the use of a macro?

Can this not be made a constant or “sealed” by some other means in Crystal?

I’m still learning, so I do apologize if this is a silly question.

1 Like

Given

class A
   def one
   end
end
class B < A
  private def one
  end
end
class C < B
  def one
  end
end

Some languages would complain about C#one overloading a private method of B. But Crystal doesn’t seem to mind. Java has a final keyword, not that I would hold Java up as a language to emulate :-)

Crystal’s inheritance rules are looser than some languages. Or they seem so, but then you realize that some rules, like requiring every derived class to duplicate the constructors of its parent, are not necessary in Crystal because it has a better way of detecting whether every constructor initializes a variable.

Am I crazy for thinking that this would be a helpful language feature? I find the need for a macro for such a common mechanism a bit “yuck”. (On the part of Crystal, not your macro of course)

@asterite Maybe you could spare your opinion…

You don’t have to ask for things in the language that you could put in a library. I could certainly get this to work:

class A
  final :one

  def one
  end
end

So, this issue:

is currently open, despite some confusion.

Long ago there was this other. somewhat orthogonal issue:

I do think there is a need for this, to be honest. Not every library needs to be “nationalized” into the language, so to speak, but I do think this is a feature that would help improve the promises that the Crystal compiler is able to make. That’s important to be able to produce decent libraries in the first place, lest a hacker become too creative for their own good and write their own footgun without realizing.

I have overlooked something crucial:

This is what structs provide. I retract what I’ve posted!

The macro method only works for methods in structs and classes. The more general issue is interesting, but I have higher priorities for the coding team. Like why is the code generator getting a signal 11 on me this evening :-)

1 Like

I was a bit confused by this topic. It seems you mean overriding, not overloading.
Editing the existing posts to clarify that would probably be helpful.

2 Likes

Hm. @straight-shoota, the definition of overloading seems to involve operators having different arguments. I’m not sure if that’s what it meant when I learned C++ when that was brand new. Which is probably close to 40 years ago. I’ll fix this when I’m I’m a bit more awake