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] (ascii order)
- ! 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