简体   繁体   中英

How to make a specific method work with different number of arguments in Ruby?

I want my method add_directory to be able to work with one or two arguments. As shown in the two different versions of the method. I know that Ruby doesn't allow method overloading and as a person coming from C++ I haven't gotten the hang of it. How do I redesign my method so that I achieve the results I want? Thanks in advance.


Module RFS
  class Directory
   attr_accessor :content
   def initialize
     @content = {}
   end

   def add_file (name,file)
     @content[name]=file
   end

   def add_directory (name,subdirectory)
     @content[name] = subdirectory
   end

   def add_directory (name)
     @content[name] = RFS::Directory.new
   end
 end
end

There are several possible solutions in your case. The simplest one, probably the most correct, is to declare subdirectory as an optional parameter.

def add_directory(name, subdirectory = nil)
  if subdirectory
    @content[name] = subdirectory
  else
    @content[name] = RFS::Directory.new
  end
end

In Ruby you can simulate the overloading using the * (splat) operator and inspecting the arguments in the method. For instance

def add_directory(*names)
  # here *names is an array of 0 or more items
  # you can inspect the number of items and their type
  # and branch the method call accordingly
end

But this solution is unnecessarily complicated in your case.

oh man, Simone got to it while I was answering

I was going to suggest

def add_directory(name, subdirectory=nil)
  @content[name] = subdirectory.present? ? subdirectory : RFS::Directory.new
end

In response to Simone's splat method.

def add_directory(*args)
  @content[args[0]] = args.length > 1 ? args[1] : RFS::Directory.new
end

I don't personally like this because you have a required name param and then a optional subdirectory param. You wouldn't know if they put name first or second, or if they put name at all. it would be better to require name as the first param and catch the rest of the params in the splat

def add_directory(name, *args)
  @content[name] = args.present? ? args[0] : RFS::Directory.new
end

which turns out to be similar to the first method which just sets subdirectories to a default of nil

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM