工作日常中,突然想設計一個靈活的 Ruby 函式 universal_function
,有需要的時候可以應用。
它具有以下特點:
- 無參數調用時返回
nil
- 單一參數時有不同的處理邏輯:
- 字串:反轉
- 數字:加倍
- 數組:隨機排序
- Hash:轉換 key 為字串
- 多參數支持:
- 兩個數字相加
- 兩個 Hash 合併
- 兩個數組組合成 Hash
- 三個數字求和
- 支持關鍵字參數過濾和轉換
- 支持區塊操作,可以對輸入進行變換
實際程式:
def universal_function(*args, **kwargs, &block)
# 處理不同類型的輸入和場景
# 1. 如果沒有參數,返回 nil
return nil if args.empty? && kwargs.empty? && !block_given?
# 2. 如果只有一個參數,執行基本處理
if args.length == 1 && kwargs.empty? && !block_given?
case args.first
when String
return args.first.reverse
when Numeric
return args.first * 2
when Array
return args.first.shuffle
when Hash
return args.first.transform_keys(&:to_s)
else
return args.first
end
end
# 3. 處理多個參數的情況
if args.any?
case args.length
when 2
return args.first + args.last if args.all? { |arg| arg.is_a?(Numeric) }
return args.first.merge(args.last) if args.all? { |arg| arg.is_a?(Hash) }
return args.first.zip(args.last).to_h if args.all? { |arg| arg.is_a?(Array) }
when 3
return args.sum if args.all? { |arg| arg.is_a?(Numeric) }
end
end
# 4. 處理關鍵字參數
if kwargs.any?
case
when kwargs.key?(:filter)
return args.first.select { |item| kwargs[:filter].call(item) } if args.first.is_a?(Array)
when kwargs.key?(:transform)
return args.first.map { |item| kwargs[:transform].call(item) } if args.first.is_a?(Array)
end
end
# 5. 處理區塊
if block_given?
return args.map(&block) if args.any?
return kwargs.transform_values(&block) if kwargs.any?
end
# 6. 最後的備用返回
args.any? ? args : kwargs
end
# 示範使用
puts universal_function(5) # 輸出: 10
puts universal_function("hello") # 輸出: olleh
puts universal_function([1, 2, 3]) # 輸出: 隨機排序的數組
puts universal_function({a: 1, b: 2}) # 輸出: {"a"=>1, "b"=>2}
puts universal_function(1, 2) # 輸出: 3
puts universal_function([1, 2, 3], filter: ->(x) { x.even? }) # 輸出: [2]
puts universal_function([1, 2, 3]) { |x| x * 2 } # 輸出: [2, 4, 6]