Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to restrict type of a function argument

Let's say I have a following function:

def encode(obj)
  case obj
  when Int32
    "i#{obj}e"
  when String
    "#{obj.size}:#{obj}"
  when Symbol
    encode(obj.to_s)
  when Array
    obj.reduce "a" {|acc, i| acc + encode(i)} + "e"
  else
    raise ArgumentError.new "Cannot encode argument of class '#{obj.class}'"
  end
end

And I want to get rid of that else branch to make a compile-time check for the type of an argument. I can write something like this:

def encode(obj : Int32 | String | Symbol | Array)

In this case it's ok. But what if have a bigger list of types? Is there a more elegant way to do this? I want compiler to check that this function accepts only those types that are matched in the case expression.

like image 244
Anon Avatar asked Jan 02 '23 10:01

Anon


1 Answers

Overloading to the rescue:

def encode(obj : Int32)
  "i#{obj}e"
end

def encode(obj : String)
  "#{obj.size}:#{obj}"
end

def encode(obj : Symbol)
  encode(obj.to_s)
end

def encode(obj : Array(String))
  obj.reduce "a" { |acc, i| acc + encode(i) } + "e"
end
like image 136
WPeN2Ic850EU Avatar answered Jan 13 '23 15:01

WPeN2Ic850EU