Overloading constructor

Hi there,

so I am currently working on a Julia script that reads unformatted binary Fortran files.
For this, I am using the package “FortranFiles.jl”. After importing, one can create FortranFile objects with the command

FortranFile("filename.bin")

and then read the content of the file with the base method

read(f, **kwargs)

However, it is not possible to use this nice

FortranFile(filname) do f 
     some_code
   end

In the documentation of the open function, I found that one of the versions of the open function is defined as

function open(f::Function, args...; kwargs...)
    io = open(args...; kwargs...)
    try
        f(io)
    finally
        close(io)
    end
end

But if I do the same thing with the FortranFile, i.e. I define

function FortranFile(f::Function, args...; kwargs...)
    io = FortranFile(args...; kwargs...)
    try
        f(io)
    finally
        close(io)
    end
end 

Julia seems to forget the original FortranFile constructor. Every time I call the function above in

FortranFile(filname) do f

construct I get a method error and when I run

methods(FortranFile)

I only get the function I defined.

Can someone tell me, how I properly define the function?

It looks like you are trying to extend a method from an existing package, FortranFiles.jl.

If you want to extend a method, you must either:

  1. Explicitly import it as opposed to just using the package.
  2. Explicitly provide the module name in your function declaration.
import FortranFiles: FortranFile

function FortranFile(f::Function, args...; kwargs...)
    # ...
end

Or

using FortranFiles

function FortranFiles.FortranFile(f::Function, args...; kwargs...)
    # ...
end

I should note that you may be committing type piracy here.

https://docs.julialang.org/en/v1/manual/style-guide/#Avoid-type-piracy

This may be fine if you are writing an end-user application, but would be an issue if you are planning to publish a package for others to use.

It may be better to fork the package and add this function there. I see the package has not been updated in a while (4 years), but you could try a pull request. If that fails, perhaps you could consider taking over maintainership.

5 Likes

Thank you! That is exactly what I was looking for!