Class: Hyde::PatternMatching::Glob

Inherits:
Object
  • Object
show all
Defined in:
lib/hyde/pattern_matching/glob.rb

Overview

Implements glob-like pattern matching. Exact specifications for globbing rules:

"/"

  • act as directory separators
  • multiple slashes (i.e. "///") are the same as one slash ("/")
  • slashes are stripped at start and end of an expression or path
  • slashes are not matched by anything but the globstar ("**")

"" ( regexp: /([^/])/ )

  • matches from 0 to any number of characters
  • does not match nothing if placed between two slashes (i.e "/*/")
  • result is captured in an array
  • stops at slashes
  • greedy (matches as much as possible)

"*" ( regexp: /(.)/ )

  • matches any number of characters
  • matches slashes ("/")
  • result is captured in an array
  • does not stop at slashes
  • greedy (matches as much as possible)

"[...]+" ( regexp: itself, ! and ^ at the start are interchangeable )

  • acts like a regexp range
  • matches any characters, including slashes if specified
  • matches any number of characters
  • valid ways to specify a range: [A-z], [a-z], 9-z
  • ! or ^ at the start invert meaning (any character not in range)
  • result is captured in an array

":name" ( regexp: acts like a named group for /[^/]*/ )

  • acts like * as defined above
  • result is captured in a hash with "name" as key
  • name allows alphanumeric characters and underscores
  • ignored unless placed between two slashes

"(name|name2|...)" ( regexp: itself )

  • matches any of (full keywords) name, name2, ...
  • result is captured in an array
  • each name may include only these groups of characters:
    • alphanumeric
    • slashes
    • underscores
    • dashes

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pattern) ⇒ Glob

Returns a new instance of Glob.

Parameters:

  • input (String)

    Glob pattern



56
57
58
59
60
61
62
63
# File 'lib/hyde/pattern_matching/glob.rb', line 56

def initialize(pattern)
  pattern = Hyde::PatternMatching.canonicalize(pattern)
  pieces = pattern.split(TOKENS)
  # @type [Array<String,Integer>]
  @index = build_index(pieces)
  # @type [Regexp]
  @glob = build_regexp(pieces)
end

Class Method Details

.can_convert?(input) ⇒ Boolean

Test if input is convertible to a Glob and if it should be converted

Parameters:

  • input

Returns:

  • (Boolean)

    Input can be safely converted to Glob



96
97
98
99
# File 'lib/hyde/pattern_matching/glob.rb', line 96

def self.can_convert?(input)
  input.is_a? String and
    input.match?(TOKENS)
end

Instance Method Details

#match(input) ⇒ Array(String,Array,Hash), FalseClass

Match the string and assign matches to parameters. Returns:

  • Unmatched part of a string
  • Unnamed parameters
  • Named parameters

Parameters:

  • input (String)

    String to match

Returns:

  • (Array(String,Array,Hash))
  • (FalseClass)

    if input doesn't match glob



74
75
76
77
78
79
80
81
82
# File 'lib/hyde/pattern_matching/glob.rb', line 74

def match(input)
  input = Hyde::PatternMatching.canonicalize(input)
  result = input.match(@glob)
  return false unless result

  input = result.post_match
  named_params, params = assign_by_index(@index, result.captures)
  [input, params, named_params]
end

#match?(input) ⇒ Boolean

Test if a string can be matched. Lighter version of match that doesn't assign any variables.

Parameters:

  • input (String)

    String to match

Returns:

  • (Boolean)


88
89
90
91
# File 'lib/hyde/pattern_matching/glob.rb', line 88

def match?(input)
  input = Hyde::PatternMatching.canonicalize(input)
  input.match? @glob
end