File: path.rb

package info (click to toggle)
ruby-backports 3.6.1-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 2,460 kB
  • ctags: 703
  • sloc: ruby: 6,195; makefile: 24
file content (55 lines) | stat: -rw-r--r-- 2,134 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
require 'backports/tools/alias_method_chain'
require 'backports/tools/arguments'

module Backports
  # Metaprogramming utility to convert the first file argument to path
  def self.convert_first_argument_to_path(klass, selector)
    mod = class << klass; self; end
    unless mod.method_defined? selector
      warn "#{mod}##{selector} is not defined, so argument can't converted to path"
      return
    end
    arity = mod.instance_method(selector).arity
    last_arg = []
    if arity < 0
      last_arg = ["*rest"]
      arity = -1-arity
    end
    arg_sequence = (["file"] + (1...arity).map{|i| "arg_#{i}"} + last_arg + ["&block"]).join(", ")

    alias_method_chain(mod, selector, :potential_path_argument) do |aliased_target, punctuation|
      mod.module_eval <<-end_eval, __FILE__, __LINE__ + 1
        def #{aliased_target}_with_potential_path_argument#{punctuation}(#{arg_sequence})
          file = Backports.convert_path(file)
          #{aliased_target}_without_potential_path_argument#{punctuation}(#{arg_sequence})
        end
      end_eval
    end
  end

  # Metaprogramming utility to convert all file arguments to paths
  def self.convert_all_arguments_to_path(klass, selector, skip)
    mod = class << klass; self; end
    unless mod.method_defined? selector
      warn "#{mod}##{selector} is not defined, so arguments can't converted to path"
      return
    end
    first_args = (1..skip).map{|i| "arg_#{i}"}.join(",") + (skip > 0 ? "," : "")
    alias_method_chain(mod, selector, :potential_path_arguments) do |aliased_target, punctuation|
      mod.module_eval <<-end_eval, __FILE__, __LINE__ + 1
        def #{aliased_target}_with_potential_path_arguments#{punctuation}(#{first_args}*files, &block)
          files = files.map{|f| Backports.convert_path(f) }
          #{aliased_target}_without_potential_path_arguments#{punctuation}(#{first_args}*files, &block)
        end
      end_eval
    end
  end

  def self.convert_path(path)
    try_convert(path, IO, :to_io) ||
    begin
      path = path.to_path if path.respond_to?(:to_path)
      try_convert(path, String, :to_str) || path
    end
  end
end