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

Unhelpful error message (Error: unexpected token: "(") when defining method that starts with a capital letter. #15316

Open
Zopolis4 opened this issue Dec 29, 2024 · 5 comments
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc.

Comments

@Zopolis4
Copy link

Bug Report

The following code fails to compile:

def Foo(bar)
 puts "qux #{bar}"
end

Foo("quux")

with the following error:

In temp.cr:1:8

 1 | def Foo(bar)
            ^
Error: unexpected token: "("

I believe the starting with the capital letter is the issue, because renaming the method to foo or fFoo or _Foo fixed it (successfully printing the output of qux quux), but the error message does not make that clear.

I was additionally unable to find any documentation detailing that method names couldn't start with capital letters, so assuming I am not incorrect about the cause of the error it may help to update the relevant documentation to take note of that in addition to updating the error message.

Tested on:

Crystal 1.14.0 [dacd97bcc] (2024-10-09)

LLVM: 18.1.6
Default target: x86_64-unknown-linux-gnu
@Zopolis4 Zopolis4 added the kind:bug A bug in the code. Does not apply to documentation, specs, etc. label Dec 29, 2024
@devnote-dev
Copy link
Contributor

You're on the right track — Crystal allows def Foo.bar syntax to define a method on a type without explicitly reopening it, I think in this case it's expecting the remaining part (.bar), when it should rightfully error on "Foo".

@Zopolis4
Copy link
Author

Is that also the case for def FOO.bar?

Because I get the same when doing:

def FOO(bar)
 puts "qux #{bar}"
end

FOO("quux")

which then gives

In EEEE.cr:1:8

 1 | def FOO(bar)
            ^
Error: unexpected token: "("

@devnote-dev
Copy link
Contributor

Yes, any identifier that starts with a capital letter is initially parsed as a constant, which usually refers to a type.

@Blacksmoke16
Copy link
Member

This is called out in https://crystal-lang.org/reference/1.14/syntax_and_semantics/methods_and_instance_variables.html:

Method names begin with a lowercase letter and, as a convention, only use lowercase letters, underscores and numbers.

@Zopolis4
Copy link
Author

Got it, thanks. In that case, its only the error message that needs to be updated to point to the actual problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc.
Projects
None yet
Development

No branches or pull requests

3 participants