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

Fix handling of double dashes -- in crystal eval command #15477

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

kojix2
Copy link
Contributor

@kojix2 kojix2 commented Feb 14, 2025

This is the main part of the pull request #15474


The purpose of this pull request is to pass arguments after a double dash to the program when using the eval command.

crystal eval 'puts ARGV' -- meow neigh

Expected behavior

["meow", "neigh"]

Actual behavior

syntax error in eval:1
Error: unexpected token: "meow"

Workaround

By using two double dashes, you can pass arguments to the program as expected.

crystal eval 'puts ARGV' -- -- meow neigh

The reason for this behavior is that the OptionParser stops at -- by default, and removes --.
You need to use unknown_args to distinguish between arguments that were before -- and arguments that were after --.

This issue was reported to the forum.

@straight-shoota straight-shoota added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler:cli labels Feb 14, 2025
src/compiler/crystal/command/eval.cr Outdated Show resolved Hide resolved
src/compiler/crystal/command/eval.cr Outdated Show resolved Hide resolved
kojix2 and others added 2 commits February 14, 2025 23:27
Co-authored-by: Johannes Müller <straightshoota@gmail.com>
Co-authored-by: Johannes Müller <straightshoota@gmail.com>
@straight-shoota
Copy link
Member

Ah now the code fails because program_source is a closure.
In other situations like that we introduce a separate local variable (e.g. opt_program_source) as the closured var and then assign it to the actual variable after the block.

@kojix2
Copy link
Contributor Author

kojix2 commented Feb 14, 2025

I tried the following code, but it did not work. It is nighttime in Japan. Good night.

# Implementation of the `crystal eval` command

class Crystal::Command
  private def eval
    compiler = new_compiler
    program_source = ""
    opt_program_source = nil
    program_args = [] of String

    parse_with_crystal_opts do |opts|
      opts.banner = "Usage: crystal eval [options] [source]\n\nOptions:"
      setup_simple_compiler_options compiler, opts

      opts.unknown_args do |before_dash, after_dash|
        opt_program_source = before_dash.join " "
        program_args = after_dash
      end
    end
  
    if opt_program_source.nil?
      program_source = STDIN.gets_to_end
    else
      program_source = opt_program_source
    end
    sources = [Compiler::Source.new("eval", program_source)]

    output_filename = Crystal.temp_executable "eval"

    compiler.compile sources, output_filename
    execute output_filename, program_args, compiler
  end
end
In src/compiler/crystal/command/eval.cr:25:45

 25 | sources = [Compiler::Source.new("eval", program_source)]
                                              ^-------------
Error: expected argument #2 to 'Crystal::Compiler::Source.new' to be String, not (String | Nil)

Overloads are:
 - Crystal::Compiler::Source.new(filename : String, code : String)
make: *** [Makefile:247: .build/crystal] Error 1

@straight-shoota
Copy link
Member

I pushed a commit with the change I had in mind.

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. topic:compiler:cli
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants