Open owen2345 opened 3 years ago
Yup. That's actually how ICR works. I thought we had a message that printed when you ran icr to actually tell you this 🤔 this thing... not sure why it didn't show for you.
Since Crystal doesn't have an interpreter, the only way to evaluate the code is to shove it in to a file, compile that file, and run it. Each time you run some code, it appends to that temp file, compiles it and runs it. If it didn't do this, then variables wouldn't work line to line. So in your case, it's calling Article.create
every time because each time you hit enter
, it runs that code.
Unfortunately, until Crystal gets a built-in repl, this is just how it's going to work. Here's more discussion on it https://github.com/crystal-community/icr/issues/79 if you'd like to chime in on that.
Hey @jwoertink You are right! I am working in a PR to improve this feature as the following:
regular
commands, search for all command variables, sample: var1 = 10; var2 = Article.first; var3 = Article.create(name: "A1")
serialized_article = Crystalizer::JSON.serialize(var2)
@commands << Command.new(type, command, vars_cmd: local_vars.map { |name, val|
"#{name} = Crystalizer::JSON.deserialize(#{Crystalizer::JSON.serialize(value)}, #{typeof(val)})" }.join("; ")
)
vars_cmd
for regular
commands instead of the command entered by the user $> require "./config/application.cr" # amber application
$> require "crystalizer/json" # (de)serializer library
$> a=Article.first; ss = Crystalizer::JSON.serialize(a); dd=Crystalizer::JSON.deserialize(ss, typeof(a)); puts [a && a.number, dd && dd.number] # ==> [10, 10]
All points are working as expected except #1 for which I could not find the way to retrieve all the local variables from the command, something like this: https://ruby-doc.org/core-3.0.1/Kernel.html#method-i-local_variables
I tried with instance_vars
but it does not return the expected vars. Sample:
macro print_vars
var1 = 10
var2 = 10
{% puts @type.instance_vars %}
end
print_vars # ==> []
Maybe you @jwoertink or some else can help me with this and then create the corresponding PR.
Best regards!
@owen2345 Could you explain how this will work when a variable is, for example, a file that points to an open file descriptor? The file descriptor will be gone.
You just have to accept the limitations of icr. The other way to do this would be:
I think there's no fix for icr that will work all the time.
Do you know about the command crystal play
? Maybe that's something that would be more helpful to you in this case.
Also not every type is JSON serializable.
Finally, I saw you posted a request on the forums to get the local vars. You don't need that in the compiler. You can parse the source code provided to icr
and gather local vars there.
Hey @owen2345, I applaud you for attempting this. I tried for a bit with the idea of using something like redis to store data between compiles, and memoize each call. Crystal doesn't have a way to Marshal data though, and like @asterite said, not every type is JSON serializable, so eventually my path was bunk.
I know it's not the best answer, but really I think there's not much you can do about the limitations. If using the crystal play
doesn't work for you, an alternative could be to just add a sandbox file in your app that you can open up, add some quick code, and run as needed while in development. Maybe add that to your gitignore.
I don't want to discourage you, but I also would hate to have you waste a ton of hours and energy on something that could be better spent elsewhere.
Hey @jwoertink @asterite thanks for answering.
Of course it is possible, check this in progress PR: https://github.com/crystal-community/icr/pull/128 Note: As you mentioned before, I could not see a way to retrieve all declared variables inside a command (TODO). For now I am using a regex while a feature similar/alternative to this is implemented: https://ruby-doc.org/core-3.0.1/Kernel.html#method-i-local_variables
Hi, I am using this cli with Amber and having the following:
Every time I run any new command, all the previous commands are called again, in this case Article is being created.