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

Added @softscope macro for ease of use #1

Merged
merged 6 commits into from
Sep 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ However, for *interactive* use, especially for new users, the necessity of the `

## Usage

The `SoftGlobalScope` module exports two functions `softscope` and `softscope_include_string`:
The `SoftGlobalScope` module exports two functions `softscope` and `softscope_include_string`, and a macro `@softscope`:

You can transform the expression using `softscope(module, expression)` to automatically insert the necessary `global` keyword. For example, assuming that the module `Main` has a global variable `s` (as above), you can do:
```jl
Expand All @@ -77,8 +77,20 @@ julia> softscope(Main, :(for i = 1:10
global s += i
end)
```
You can then execute the statement with `eval`. Alternatively, you can execute an entire sequence of statements
using "soft" global scoping rules via `softscope_include_string(module, string, filename="string")`:
You can then execute the statement with `eval`. Alternatively, you can decorate the expression with the `@softscope` macro:
```jl
julia> s = 0;

julia> @softscope for i = 1:10
s += i
end

julia> s
55
```
This macro should only be used in the global scope (e.g., via the REPL); using this macro within a function is likely to lead to unintended consequences.

You can execute an entire sequence of statements using "soft" global scoping rules via `softscope_include_string(module, string, filename="string")`:
```jl
julia> softscope_include_string(Main, """
s = 0
Expand Down
48 changes: 45 additions & 3 deletions src/SoftGlobalScope.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,23 @@ julia> softscope(Main, :(for i = 1:10
global s += i
end)
```
You can then execute the statement with `eval`. Alternatively, you can execute an entire sequence of statements
using "soft" global scoping rules via `softscope_include_string`:
You can then execute the statement with `eval`. Alternatively, you can decorate
the expression with the `@softscope` macro:
```jl
julia> s = 0;

julia> @softscope for i = 1:10
s += i
end

julia> s
55
```
This macro should only be used in the global scope (e.g., via the REPL); using
this macro within a function is likely to lead to unintended consequences.

You can execute an entire sequence of statements using "soft" global scoping
rules via `softscope_include_string`:
```jl
julia> softscope_include_string(Main, \"\"\"
s = 0
Expand All @@ -44,7 +59,7 @@ On Julia 0.6, `softscope` is the identity and `softscope_include_string` is equi
`include_string`, since the `global` keyword is not needed there.
"""
module SoftGlobalScope
export softscope, softscope_include_string
export softscope, softscope_include_string, @softscope

if VERSION < v"0.7.0-DEV.2308" # before julia#19324 we don't need to change the ast
softscope(m::Module, ast) = ast
Expand Down Expand Up @@ -128,6 +143,33 @@ scoping rules for the global variables defined in `m`, returning the new express
"""
softscope

if VERSION < v"0.7.0-DEV.481" # the version that __module__ was introduced
macro softscope(ast)
esc(softscope(current_module(), ast))
end
else
macro softscope(ast)
esc(softscope(__module__, ast))
end
end

"""
@softscope(expr)

Apply "soft" scoping rules to the argument of the macro. For example
```jl
julia> s = 0;

julia> @softscope for i = 1:10
s += i
end

julia> s
55
```
"""
:(@softscope)

"""
softscope_include_string(m::Module, code::AbstractString, filename::AbstractString="string")

Expand Down
6 changes: 6 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,9 @@ end
@test softscope_include_string(TestMod, "for i=1:10; a += 1; end; a") == 10
@test softscope_include_string(TestMod, "aa=0; for i=1:10; aa += i; end; aa") == 55
end

@testset "softscope_macro" begin
Core.eval(TestMod, :(global a = 0 ; using SoftGlobalScope))
@test Core.eval(TestMod, :(@softscope (for i=1:10; a += 1; end; a))) == 10
@test Core.eval(TestMod, :(@softscope (amacro=0; for i=1:10; amacro += i; end; amacro))) == 55
end