Skip to content

Add support for .iex files #1100

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

Merged
merged 20 commits into from
May 22, 2013
Merged

Add support for .iex files #1100

merged 20 commits into from
May 22, 2013

Conversation

alco
Copy link
Member

@alco alco commented May 21, 2013

This is the first half of implementing #1062.

In the description of .iex files I mention the f() helper which would erase variable bindings. IEx does not have it yet, but it would be really useful as the last expression in an .iex file if the user doesn't want to keep var bindings. Or, perhaps, there is another way to scope the code in the .iex file lexically so it doesn't leak into the shell if the user doesn't want it to?

The fact that it leaks by default is by design.


@doc false
def print_exception(exception) do
print_stacktrace System.stacktrace, fn ->
Copy link
Member

Choose a reason for hiding this comment

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

You need to explicitly pass the stacktrace as argument from the catch block. By calling another function, you may modify the stacktrace (it happens when the module is first accessed at runtime for example).

@alco
Copy link
Member Author

alco commented May 21, 2013

The fact that it leaks by default is by design.

We could change it though. I.e. ignore new bindings by default, but provide some kind of export macro:

# .iex
value = 13
IEx.Helpers.export value


# Locates and loads an .iex file from one of predefined locations
defp load_dot_iex(config) do
path = Enum.find [".iex", "~/.iex"], File.regular?(&1)
Copy link
Member

Choose a reason for hiding this comment

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

File.regular? doesn't expand "~/.iex", does it?

@josevalim
Copy link
Member

Added some comments, everything else is perfect. So feel free to merge whenever you are ready!

@alco
Copy link
Member Author

alco commented May 21, 2013

@josevalim Thanks. What about the f() helper I commented about here? It's mentioned in the doc right now.

@@ -201,4 +238,28 @@ defmodule IEx do
defp run_after_spawn do
lc fun inlist Enum.reverse(after_spawn), do: fun.()
end

# Locates and loads an .iex file from one of predefined locations
Copy link
Member

Choose a reason for hiding this comment

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

One last feedback, can we move this to IEx.Server? Then all code evaluation will be in IEx.Server and there will be no need for IEx.Util too.

@josevalim
Copy link
Member

I am ok with supporting the f() helper too. Just one note, currently the .iex file is not going to have direct access to f() because it is being evaluated before IEx.Helpers is imported, which happens in IEx.Server. Maybe this is another reason to move the current load_dot_iex to inside the server. :)

@josevalim
Copy link
Member

Another note, maybe we should call it forget_bindings() or forget_vars(). I don't think it will be such a common function to deserve the f() shortcut. :)

Sample contents of a local .iex file:

# source another .iex file, ~/.iex in this case
Code.require_file ".iex", "~"
Copy link
Member

Choose a reason for hiding this comment

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

It just came to my mind that a variable set inside the required file won't propagate to the iex binding. Maybe we should support a import_file() inside IEx.Helpers after all as you originally proposed that people would be able to call any time.

@josevalim
Copy link
Member

On the other hand, since we can override variables in Elixir, I don't really see the pressing concern for adding f() or forget_binding(). :) I wouldn't worry about it for now, just remove it from the docs. :)

@alco
Copy link
Member Author

alco commented May 22, 2013

@josevalim I'm ready to rebase on master and merge.

end

defmacro import_file(_) do
raise "import_file/1 expects a literal binary as its argument"
Copy link
Member

Choose a reason for hiding this comment

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

raise ArgumentError, message: "import_file/1 expects a literal binary as its argument" as it is strictly an argument error :D

@alco
Copy link
Member Author

alco commented May 22, 2013

@josevalim Please take another look.

@alco
Copy link
Member Author

alco commented May 22, 2013

Wait a minute, I think we got conflicting changes in Changelog.

alco added 5 commits May 22, 2013 15:57
Since the argument to import_file/1 has to be a literal, it's not that
difficult to construct desired path by hand
It allows one to override the standard locations where .iex is searched
and also makes it possible to disable .iex loading completely.
josevalim pushed a commit that referenced this pull request May 22, 2013
Add support for .iex files
@josevalim josevalim merged commit 6e8fb6c into elixir-lang:master May 22, 2013
@josevalim
Copy link
Member

❤️ 💚 💙 💛 💜

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

Successfully merging this pull request may close these issues.

2 participants