Reputation: 12371
I want to use an object in Julia, which can be initialized by a function. It's like a function pointer in C.
Here is my goal:
I have a julia script and a julia module.
In this script, I have an array.
The module needs to be able to add some elements into this array.
#script
liste = Int64[]
function addElement(e)
liste.push(e)
end
include("path/mymodule.jl")
myModule.setAddElementFunc(addElement)
myModule.execute() # error: wrong number of parameter
#mymodule.jl
module myModule
export setAddElementFunc
export execute
addElementFunc = ()->()
funciton setAddElementFunc(fn)
addElementFunc = fn
end
function execute()
addElementFunc(3)
end
end
Basically, my idea is:
in the module, we can't do anything BUT add
. I need to do such a structure because my job is to code the julia script and some other people will code the module. So I want to limit his right to keep the liste safe, in this case, he can just add elements.
Upvotes: 2
Views: 826
Reputation: 5325
A "function pointer" is just a complicated C construction that is necessary because there is no other way of having a different name that you can use to refer to functions.
In Julia, you just literally create another name that refers to the same function object, as I had already done in my first answer, e.g.
hello() = "hi"
goodbye() = "ciao"
f = hello # f is a "function pointer"
f()
f = goodbye
f()
You can easily put functions inside other data structures, e.g. a dictionary:
greeting = Dict("hello" => hello, "goodbye" => goodbye)
f = greeting["hello"]
f()
Upvotes: 0
Reputation: 5325
To generate a new type in Julia we can do something like
type MyArray{T}
elements::Vector{T}
my_value::Int
end
This automatically makes a couple of default constructors for you. You can make an object of your type by feeding it the initial values for each of its fields.
v = MyArray([3, 5], 17)
In Julia, functions do not live inside objects, but rather are methods defined outside the objects. In this sense, objects in Julia are similar to structs in C, except that they can (and, usually, should) be parametrised by type, as in this example (the {T}
).
In this case, for example, you can simply define your own method of the generic function push!
from base Julia, to act on objects of your new type:
push!(x::MyArray, value) = push!(x.elements, value)
Now you can do
push!(v, 4)
to add the value 4 to your object.
You should read the Julia manual and have a look at some tutorials for more information on defining types. Let us know if anything is not clear.
Upvotes: 3
Reputation: 5746
Although @David is compliantly right, I would like to point out the usefulness of global
keyword. I like to think of it here as an CPP this
alike keyword in Julia-Lang.
module test
addMsgFunc=()->()
function getAddMsgFunc(fn)
global addMsgFunc = fn
end
function show()
println("xxxxx")
end
end
julia> addMsgFunc
ERROR: UndefVarError: addMsgFunc not defined
julia> test.addMsgFunc();
julia> test.getAddMsgFunc(test.show);
julia> test.addMsgFunc()
xxxxx
julia> addMsgFunc # Its in global but in another scope
ERROR: UndefVarError: addMsgFunc not defined
julia> test.addMsgFunc=()->() # You cant assign to it normally
ERROR: cannot assign variables in other modules
Upvotes: 1
Reputation: 5325
It is not completely clear what you want to do. One possibility is the following:
function getAddMsgFunc(fn)
fn # just return the function that is passed in
end
function my_show()
println("xxxxx")
end
addMsgFunc = getAddMsgFunc(my_show)
addMsgFunc()
Functions are first-class objects in Julia, which means that you can just pass them around by name.
Upvotes: 1