This took a while to show up and may have been missed.

On Saturday, 28 November 2015 12:19:29 UTC-5, Curtis Vogt wrote:
>
> I've been working on a package Mocking.jl 
> <https://github.com/invenia/Mocking.jl> which allows developers to 
> temporarily overwrite a method in order to facilitate testing. I've got 
> everything working pretty well with the exception of the creation of a new 
> macro which is suppose to ensure that Julia doesn't inline or optimize the 
> call in such a way that the originally specified call can be overwritten:
>
> julia> function myfunc(filename)
>
>            readall(open(filename))
>
>        end
>
> myfunc (generic function with 1 method)
>
>
> julia> myfunc("foo")
>
> ERROR: SystemError: opening file foo: No such file or directory
>
>  in open at ./iostream.jl:90
>
>  in myfunc at none:2
>
>
> julia> Base.open(name::AbstractString) = IOBuffer("bar")
>
> WARNING: Method definition open(AbstractString) in module Base at 
> iostream.jl:99 overwritten in module Main at none:1.
>
> open (generic function with 8 methods)
>
>
> julia> myfunc("foo")  # Open call within `myfunc` is not overwritten
>
> ERROR: SystemError: opening file foo: No such file or directory
>
>  in open at ./iostream.jl:90
>
>  in myfunc at none:2
>
>
> I can get this to work correctly with by adjusting the myfunc slightly:
>
>
> julia> function myfunc(filename)
>
>            readall([open([filename]...)]...)
>
>        end
>
> myfunc (generic function with 1 method)
>
>
> julia> myfunc("foo")
>
> ERROR: SystemError: opening file foo: No such file or directory
>
>  in open at ./iostream.jl:90
>
>  in open at iostream.jl:99
>
>  in myfunc at none:2
>
>
> julia> Base.open(name::AbstractString) = IOBuffer("bar")
>
> WARNING: Method definition open(AbstractString) in module Base at 
> iostream.jl:99 overwritten in module Main at none:1.
>
> open (generic function with 8 methods)
>
>
> julia> myfunc("foo")
>
> "bar"
>
>
> But this makes forces people to change their code and make it harder to 
> read. Not to mention that this is just fooling the compiler into getting 
> the behaviour I want. I would prefer to use a macro to get this behaviour 
> and I managed to get the following horrible macro to work:
>
>
>
> julia> macro fix(ex)
>
>            name = gensym()
>
>            :(@generated function $name() $ex end; $name())
>
>        end
>
>
> julia> function myfunc(filename)
>
>            @fix readall(open(filename))
>
>        end
>
> myfunc (generic function with 1 method)
>
>
> julia> myfunc("foo")
>
> ERROR: SystemError: opening file foo: No such file or directory
>
>  in open at ./iostream.jl:90
>
>  in open at iostream.jl:99
>
>  in #2###6995 at none:3
>
>  in myfunc at none:2
>
>
> julia> Base.open(name::AbstractString) = IOBuffer("bar")
>
> WARNING: Method definition open(AbstractString) in module Base at 
> iostream.jl:99 overwritten in module Main at none:1.
>
> open (generic function with 8 methods)
>
>
> julia> myfunc("foo")
>
> "bar"
>
>
> Does anyone have any suggestions on how I can improve this macro and get 
> this behaviour? Bonus points if someone can tell me a good way of 
> determining if the macro is being called from within a `Pkg.test(...)` 
> process.
>

Reply via email to