Search code examples
crystal-lang

Crystal How to check if the block argument is given inside the function


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.


Solution

  • 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