i thiink pass a function to other function or method.but i dont't konw the function's prototype? i try pass a Pointer,but complier tell me function can't take address
def fn1
puts "test"
end
fn1_pointer = pointerof(fn1)
def pass_fn( s )
s.value
end
pass_fn (fn1_pointer)
then, i change a way. i make the function to a String and invoke function recive a block,but how do i cover Strings to proc?
def test_m(x,y)
puts x
{x,y}
end
def exec_method(&block : Int32,String -> )
block.call(3,"test")
end
def t_fn
a = "test_m(Int32, String)"
proc_t = -> a #how do i excute a ?
exec_method &proc_t
end
i just think get as javascript's evel function.
thanks for you help~~~
Questions about language design are better asked on stackoverflow: https://stackoverflow.com/tags/crystal-lang (they're not an issue).
Anyway, you can't assign or reference a function. You must use blocks instead.
They can be implicit (useful for immediate execution):
def call
yield 3, "test"
end
call do |x, y|
puts x
{x, y}
end
Or explicit (useful to store callbacks for later use):
def call(block)
block.call(3, "test")
end
fn = ->(x, y) {
puts x
{x, y}
}
call(fn)
Or explicitely captured:
def call(&block)
block.call(3, "test")
end
call do |x, y|
puts x
{x, y}
end
Actually, you can do it, you use ->
followed by the function name:
def fn1
puts "test"
end
def pass_fn(s)
s.call # you use `call` to invoke it, because it will be a Proc
end
fn1_pointer = ->fn1 # This is how you do it
pass_fn (fn1_pointer)
If the function/method has arguments, you must specify their types:
def fn1(arg)
puts arg * 2
end
def pass_fn(s)
s.call(10)
end
fn1_pointer = ->fn1(Int32)
pass_fn (fn1_pointer)
You can also get a Proc from an instance method:
def pass_fn(s)
puts s.call(/e/, "a")
end
string = "hello"
fn1_pointer = ->string.gsub(Regex, String)
pass_fn (fn1_pointer)
(though right now it won't work if it ends up being a dispatch)
However, I personally never use this feature because of the existence of blocks and anonymous functions, as @ysbaddaden mentions. This means we could decide to remove this feature before 1.0 (it simplifies the language)
(btw, it seems that syntax coloring with three backticks and cr
stopped working, we now have to use the full crystal
name... anyone has any idea what happened?)
Oh. I never noticed that feature.
I vote to drop it. I don't think many people are aware of it, less using it; the syntax may be a little confusing (until you learn it), and it requires to specify argument types, whereas blocks usually don't have to.