1 Segment的分类
- Segment. Abstract Base Class
DynamicSegment. This represents parts of the route that begin with a colon, like:action,:permalinkor:id.ControllerSegment. This is actually a subclass ofDynamicSegment. It represents to special string:controller, because it does some special recognition on those strings. (We’ll cover that more in the next article).PathSegment. This is for segments that start with an asterisk, and which represent the remainder of the path. Routes like"/file/*path"use aPathSegment.StaticSegment. This is any static text in your route that must be matched (or generated) verbatim. If you have a path like"/one/two", the strings"one"and"two"are both static segments.DividerSegment. This is any segment that is used to delimit the other segments. Generally, this will be the forward slash character, but also includes commas, periods, semicolons, and question marks.
2 实现
先看看Segment实现
- class Segment #:nodoc:
- RESERVED_PCHAR = ':@&=+$,;'
- UNSAFE_PCHAR = Regexp.new("[^#{URI::REGEXP::PATTERN::UNRESERVED}#{RESERVED_PCHAR}]", false, 'N').freeze
- attr_accessor :is_optional
- alias_method :optional?, :is_optional
- def initialize
- self.is_optional = false
- end
- def extraction_code
- nil
- end
- # Continue generating string for the prior segments.
- def continue_string_structure(prior_segments)
- if prior_segments.empty?
- interpolation_statement(prior_segments)
- else
- new_priors = prior_segments[0..-2]
- prior_segments.last.string_structure(new_priors)
- end
- end
- def interpolation_chunk
- URI.escape(value, UNSAFE_PCHAR)
- end
- # Return a string interpolation statement for this segment and those before it.
- def interpolation_statement(prior_segments)
- chunks = prior_segments.collect { |s| s.interpolation_chunk }
- chunks << interpolation_chunk
- "/"#{chunks * ''}/"#{all_optionals_available_condition(prior_segments)}"
- end
- def string_structure(prior_segments)
- optional? ? continue_string_structure(prior_segments) : interpolation_statement(prior_segments)
- end
- # Return an if condition that is true if all the prior segments can be generated.
- # If there are no optional segments before this one, then nil is returned.
- def all_optionals_available_condition(prior_segments)
- optional_locals = prior_segments.collect { |s| s.local_name if s.optional? && s.respond_to?(:local_name) }.compact
- optional_locals.empty? ? nil : " if #{optional_locals * ' && '}"
- end
- # Recognition
- def match_extraction(next_capture)
- nil
- end
- # Warning
- # Returns true if this segment is optional? because of a default. If so, then
- # no warning will be emitted regarding this segment.
- def optionality_implied?
- false
- end
- end
本文介绍了一种用于解析和生成路由的Segment类。该类通过不同的子类如StaticSegment、DynamicSegment等来处理静态和动态路由段。具体实现了路由匹配、字符串结构生成等功能,并详细解释了各个方法的作用。
994

被折叠的 条评论
为什么被折叠?



