Class: SmartName
- Includes:
- ActiveSupport::Configurable
- Defined in:
- lib/smart_name.rb
Constant Summary collapse
- RUBYENCODING =
RUBY_VERSION !~ /^1\.8/
- OK4KEY_RE =
RUBYENCODING ? '\p{Word}\*' : '\w\*'
- JOINT_RE =
Regexp.escape joint
- @@name2nameobject =
{}
Instance Attribute Summary collapse
-
#key ⇒ Object
readonly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~.
-
#parts ⇒ Object
readonly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~.
-
#s ⇒ Object
(also: #to_s)
readonly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~.
-
#simple ⇒ Object
(also: #simple?)
readonly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~.
Class Method Summary collapse
Instance Method Summary collapse
- #==(obj) ⇒ Object
- #blank? ⇒ Boolean (also: #empty?)
- #decoded ⇒ Object
-
#initialize(str) ⇒ SmartName
constructor
A new instance of SmartName.
- #inspect ⇒ Object
- #junction? ⇒ Boolean
- #left ⇒ Object
- #left_name ⇒ Object
- #length ⇒ Object
- #nth_left(n) ⇒ Object
- #part_names ⇒ Object
- #piece_names ⇒ Object
- #pieces ⇒ Object
- #post_cgi ⇒ Object
- #pre_cgi ⇒ Object
-
#replace_part(oldpart, newpart) ⇒ Object
~~~~~~~~~~~~~~~~~~~~ MISC ~~~~~~~~~~~~~~~~~~~~.
- #right ⇒ Object
- #right_name ⇒ Object
- #safe_key ⇒ Object
-
#simple_key ⇒ Object
~~~~~~~~~~~~~~~~~~~ VARIANTS ~~~~~~~~~~~~~~~~~~~.
- #size ⇒ Object
- #tag ⇒ Object
- #tag_name ⇒ Object
- #to_absolute(context, args = {}) ⇒ Object
- #to_absolute_name(*args) ⇒ Object
- #to_name ⇒ Object
-
#to_show(*ignore) ⇒ Object
~~~~~~~~~~~~~~~~~~~~ SHOW / ABSOLUTE ~~~~~~~~~~~~~~~~~~~~.
-
#trunk ⇒ Object
Note that all n ames have a trunk and tag, but only junctions have left and right.
- #trunk_name ⇒ Object
- #url_key ⇒ Object
- #valid? ⇒ Boolean
Constructor Details
#initialize(str) ⇒ SmartName
Returns a new instance of SmartName.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/smart_name.rb', line 50 def initialize str @s = str.to_s.strip @s = @s.encode('UTF-8') if RUBYENCODING @key = if @s.index(self.class.joint) @parts = @s.split(/\s*#{JOINT_RE}\s*/) @parts << '' if @s[-1,1] == self.class.joint @simple = false @parts.map { |p| p.to_name.key } * self.class.joint else @parts = [str] @simple = true str.empty? ? '' : simple_key end @@name2nameobject[str] = self end |
Instance Attribute Details
#key ⇒ Object (readonly)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~
47 48 49 |
# File 'lib/smart_name.rb', line 47 def key @key end |
#parts ⇒ Object (readonly)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~
47 48 49 |
# File 'lib/smart_name.rb', line 47 def parts @parts end |
#s ⇒ Object (readonly) Also known as: to_s
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~
47 48 49 |
# File 'lib/smart_name.rb', line 47 def s @s end |
#simple ⇒ Object (readonly) Also known as: simple?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~ INSTANCE ~~~~~~~~~~~~~~~~~~~~~~~~~
47 48 49 |
# File 'lib/smart_name.rb', line 47 def simple @simple end |
Class Method Details
.banned_re ⇒ Object
38 39 40 |
# File 'lib/smart_name.rb', line 38 def banned_re %r{#{ (['['] + banned_array << joint )*'\\' + ']' }} end |
.new(obj) ⇒ Object
28 29 30 31 32 33 34 35 36 |
# File 'lib/smart_name.rb', line 28 def new obj return obj if self.class===obj str = Array===obj ? obj*joint : obj.to_s if known_name = @@name2nameobject[str] known_name else super str.strip end end |
.substitute!(str, hash) ⇒ Object
HACK. This doesn’t belong here. shouldn’t it use inclusions???
246 247 248 249 250 251 252 253 |
# File 'lib/smart_name.rb', line 246 def self.substitute! str, hash hash.keys.each do |var| str.gsub! var_re do |x| hash[var.to_sym] end end str end |
Instance Method Details
#==(obj) ⇒ Object
82 83 84 85 86 87 88 89 |
# File 'lib/smart_name.rb', line 82 def == obj object_key = case when obj.respond_to?(:key) ; obj.key when obj.respond_to?(:to_name) ; obj.to_name.key else ; obj.to_s end object_key == key end |
#blank? ⇒ Boolean Also known as: empty?
69 |
# File 'lib/smart_name.rb', line 69 def blank?() s.blank? end |
#decoded ⇒ Object
106 107 108 |
# File 'lib/smart_name.rb', line 106 def decoded @decoded ||= (s.index('&') ? HTMLEntities.new.decode(s) : s) end |
#inspect ⇒ Object
78 79 80 |
# File 'lib/smart_name.rb', line 78 def inspect "<#{self.class.name} key=#{key}[#{self}]>" end |
#junction? ⇒ Boolean
124 |
# File 'lib/smart_name.rb', line 124 def junction?() not simple? end |
#left ⇒ Object
126 |
# File 'lib/smart_name.rb', line 126 def left() @left ||= simple? ? nil : parts[0..-2]*self.class.joint end |
#left_name ⇒ Object
129 |
# File 'lib/smart_name.rb', line 129 def left_name() @left_name ||= left && self.class.new( left ) end |
#length ⇒ Object
67 |
# File 'lib/smart_name.rb', line 67 def length() parts.length end |
#nth_left(n) ⇒ Object
210 211 212 213 |
# File 'lib/smart_name.rb', line 210 def nth_left n # 1 = left; 2= left of left; 3 = left of left of left.... ( n >= length ? parts[0] : parts[0..-n-1] ).to_name end |
#part_names ⇒ Object
140 |
# File 'lib/smart_name.rb', line 140 def part_names() @part_names ||= parts.map &:to_name end |
#piece_names ⇒ Object
141 |
# File 'lib/smart_name.rb', line 141 def piece_names() @piece_names ||= pieces.map &:to_name end |
#pieces ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/smart_name.rb', line 143 def pieces @pieces ||= if simple? [ self ] else junction_pieces = [] parts[1..-1].inject parts[0] do |left, right| piece = [left, right] * self.class.joint junction_pieces << piece piece end parts + junction_pieces end end |
#post_cgi ⇒ Object
116 117 118 119 |
# File 'lib/smart_name.rb', line 116 def post_cgi #hmm. this could resolve to the key of some other card. move to class method? @post_cgi ||= s.gsub '~plus~', self.class.joint end |
#pre_cgi ⇒ Object
110 111 112 113 114 |
# File 'lib/smart_name.rb', line 110 def pre_cgi #why is this necessary?? doesn't real CGI escaping handle this?? # hmmm. is this to prevent absolutizing @pre_cgi ||= parts.join '~plus~' end |
#replace_part(oldpart, newpart) ⇒ Object
~~~~~~~~~~~~~~~~~~~~ MISC ~~~~~~~~~~~~~~~~~~~~
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/smart_name.rb', line 218 def replace_part oldpart, newpart oldpart = oldpart.to_name newpart = newpart.to_name if oldpart.simple? if simple? self == oldpart ? newpart : self else parts.map do |p| oldpart == p ? newpart.to_s : p end.to_name end elsif simple? self else if oldpart == parts[0, oldpart.length] if self.length == oldpart.length newpart else (newpart.parts+(parts[oldpart.length,].lines.to_a)).to_name end else self end end end |
#right ⇒ Object
127 |
# File 'lib/smart_name.rb', line 127 def right() @right ||= simple? ? nil : parts[-1] end |
#right_name ⇒ Object
130 |
# File 'lib/smart_name.rb', line 130 def right_name() @right_name ||= right && self.class.new( right ) end |
#safe_key ⇒ Object
102 103 104 |
# File 'lib/smart_name.rb', line 102 def safe_key @safe_key ||= key.gsub('*','X').gsub self.class.joint, '-' end |
#simple_key ⇒ Object
~~~~~~~~~~~~~~~~~~~ VARIANTS ~~~~~~~~~~~~~~~~~~~
94 95 96 |
# File 'lib/smart_name.rb', line 94 def simple_key decoded.underscore.gsub(/[^#{OK4KEY_RE}]+/,'_').split(/_+/).reject(&:empty?).map(&(self.class.uninflect))*'_' end |
#size ⇒ Object
68 |
# File 'lib/smart_name.rb', line 68 def size() to_s.size end |
#tag ⇒ Object
135 |
# File 'lib/smart_name.rb', line 135 def tag() @tag ||= simple? ? s : right end |
#tag_name ⇒ Object
138 |
# File 'lib/smart_name.rb', line 138 def tag_name() @tag_name ||= simple? ? self : right_name end |
#to_absolute(context, args = {}) ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/smart_name.rb', line 179 def to_absolute context, args={} context = context.to_name parts.map do |part| new_part = case part when /^_user$/i; name_proc = self.class.session and name_proc.call or part when /^_main$/i; self.class.params[:main_name] when /^(_self|_whole|_)$/i; context.s when /^_left$/i; context.trunk #note - inconsistent use of left v. trunk when /^_right$/i; context.tag when /^_(\d+)$/i pos = $~[1].to_i pos = context.length if pos > context.length context.parts[pos-1] when /^_(L*)(R?)$/i l_s, r_s = $~[1].size, !$~[2].empty? l_part = context.nth_left l_s r_s ? l_part.tag : l_part.s when /^_/ custom = args[:params] ? args[:params][part] : nil custom ? CGI.escapeHTML(custom) : part #why are we escaping HTML here? else part end.to_s.strip new_part.empty? ? context.to_s : new_part end * self.class.joint end |
#to_absolute_name(*args) ⇒ Object
206 207 208 |
# File 'lib/smart_name.rb', line 206 def to_absolute_name *args self.class.new to_absolute(*args) end |
#to_name ⇒ Object
66 |
# File 'lib/smart_name.rb', line 66 def to_name() self end |
#to_show(*ignore) ⇒ Object
~~~~~~~~~~~~~~~~~~~~ SHOW / ABSOLUTE ~~~~~~~~~~~~~~~~~~~~
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/smart_name.rb', line 161 def to_show *ignore ignore.map! &:to_name show_parts = parts.map do |part| reject = ( part.empty? or part =~ /^_/ or ignore.member? part.to_name ) reject ? nil : part end show_name = show_parts.compact.to_name.s case when show_parts.compact.empty?; self when show_parts[0].nil? ; self.class.joint + show_name else show_name end end |
#trunk ⇒ Object
Note that all n ames have a trunk and tag, but only junctions have left and right
134 |
# File 'lib/smart_name.rb', line 134 def trunk() @trunk ||= simple? ? s : left end |
#trunk_name ⇒ Object
137 |
# File 'lib/smart_name.rb', line 137 def trunk_name() @trunk_name ||= simple? ? self : left_name end |
#url_key ⇒ Object
98 99 100 |
# File 'lib/smart_name.rb', line 98 def url_key @url_key ||= decoded.gsub(/[^#{OK4KEY_RE}#{JOINT_RE}]+/,' ').strip.gsub /[\s\_]+/, '_' end |
#valid? ⇒ Boolean
72 73 74 75 76 |
# File 'lib/smart_name.rb', line 72 def valid? not parts.find do |pt| pt.match self.class.banned_re end end |