Crystal: how do i pass a function type to a function

Created on 27 Jan 2017  路  3Comments  路  Source: crystal-lang/crystal

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~~~

question

All 3 comments

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.

Was this page helpful?
0 / 5 - 0 ratings