Reputation: 177
Suppose a function defined like this:
def composition(text : String, k : Int32) : Array(String)
kmers = Array(String).new
(0 .. text.size - k).each do |i|
kmers << text[i, k]
yield text[i, k]
end
return kmers
end
How do I check if the block argument is given inside the function? If the block argument is given, kmers will be yielded. If not given, kmers will be returned as an array of strings.
Upvotes: 4
Views: 435
Reputation: 1953
In your specific situation, I would recommend Oleh's answer. However, here's a more general solution that lets you determine whether a block has been passed:
def composition(text, k, &block : String ->)
composition(text, k, block)
end
def composition(text, k, block : (String ->)? = nil)
kmers = [] of String
(0 .. text.size - k).each do |i|
s = text[i, k]
if block
block.call s
else
kmers << s
end
end
kmers
end
(For more information on Proc
syntax, see https://crystal-lang.org/reference/syntax_and_semantics/type_grammar.html#proc)
Upvotes: 2
Reputation: 34116
Such a check is impossible, because a method accepting a block (using yield
anywhere) already has a signature requiring it. But that also means that you don't need the check. If you want to make it optional, just make 2 methods like this:
# if you want to be explicit (makes no difference, this method requires a block):
# def composition(text : String, k : Int32, &block)
def composition(text : String, k : Int32)
(0 .. text.size - k).each do |i|
yield text[i, k]
end
end
# and the non block option
def composition(text : String, k : Int32) : Array(String)
kmers = [] of String
composition(text, k) do |s|
kmers << s
end
return kmers
end
Upvotes: 10