Class: Friends::Friend
- Inherits:
-
Object
- Object
- Friends::Friend
- Extended by:
- Serializable
- Defined in:
- lib/friends/friend.rb
Constant Summary collapse
- SERIALIZATION_PREFIX =
"- "
- NICKNAME_PREFIX =
"a.k.a. "
Instance Attribute Summary collapse
- #likelihood_score ⇒ Object
-
#location_name ⇒ Object
Returns the value of attribute location_name.
- #n_activities ⇒ Object
-
#name ⇒ Object
Returns the value of attribute name.
-
#tags ⇒ Object
readonly
Returns the value of attribute tags.
Class Method Summary collapse
-
.deserialization_expectation ⇒ Regexp
The string of what we expected during deserialization.
-
.deserialization_regex ⇒ Regexp
The regex for capturing groups in deserialization.
Instance Method Summary collapse
-
#add_nickname(nickname) ⇒ Object
Adds a nickname, ignoring duplicates.
-
#add_tag(tag) ⇒ Object
Adds a tag, ignoring duplicates.
-
#initialize(name:, nickname_str: nil, location_name: nil, tags_str: nil) ⇒ Friend
constructor
A new instance of Friend.
-
#regexes_for_name ⇒ Array
NOTE: For now we only match on full names or first names.
- #remove_nickname(nickname) ⇒ Object
- #remove_tag(tag) ⇒ Object
-
#serialize ⇒ String
The file serialization text for the friend.
-
#to_s ⇒ String
A string representing the friend’s name and nicknames.
Methods included from Serializable
Constructor Details
#initialize(name:, nickname_str: nil, location_name: nil, tags_str: nil) ⇒ Friend
Returns a new instance of Friend.
28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/friends/friend.rb', line 28 def initialize( name:, nickname_str: nil, location_name: nil, tags_str: nil ) @name = name @nicknames = nickname_str&.split(" #{NICKNAME_PREFIX}") || [] @location_name = location_name @tags = &.split(/\s+/) || [] end |
Instance Attribute Details
#likelihood_score ⇒ Object
110 111 112 |
# File 'lib/friends/friend.rb', line 110 def likelihood_score defined?(@likelihood_score) ? @likelihood_score : 0 end |
#location_name ⇒ Object
Returns the value of attribute location_name.
41 42 43 |
# File 'lib/friends/friend.rb', line 41 def location_name @location_name end |
#n_activities ⇒ Object
100 101 102 |
# File 'lib/friends/friend.rb', line 100 def n_activities defined?(@n_activities) ? @n_activities : 0 end |
#name ⇒ Object
Returns the value of attribute name.
40 41 42 |
# File 'lib/friends/friend.rb', line 40 def name @name end |
#tags ⇒ Object (readonly)
Returns the value of attribute tags.
42 43 44 |
# File 'lib/friends/friend.rb', line 42 def @tags end |
Class Method Details
.deserialization_expectation ⇒ Regexp
Returns the string of what we expected during deserialization.
23 24 25 |
# File 'lib/friends/friend.rb', line 23 def self.deserialization_expectation "[Friend Name]" end |
.deserialization_regex ⇒ Regexp
Returns the regex for capturing groups in deserialization.
17 18 19 20 |
# File 'lib/friends/friend.rb', line 17 def self.deserialization_regex # Note: this regex must be on one line because whitespace is important /(#{SERIALIZATION_PREFIX})?(?<name>[^\(\[@]*[^\(\[@\s])(\s+\(#{NICKNAME_PREFIX}(?<nickname_str>.+)\))?(\s+\[(?<location_name>[^\]]+)\])?(\s+(?<tags_str>(#{TAG_REGEX}\s*)+))?/ # rubocop:disable Layout/LineLength end |
Instance Method Details
#add_nickname(nickname) ⇒ Object
Adds a nickname, ignoring duplicates.
82 83 84 85 |
# File 'lib/friends/friend.rb', line 82 def add_nickname(nickname) @nicknames << nickname @nicknames.uniq! end |
#add_tag(tag) ⇒ Object
Adds a tag, ignoring duplicates.
68 69 70 71 |
# File 'lib/friends/friend.rb', line 68 def add_tag(tag) @tags << tag @tags.uniq! end |
#regexes_for_name ⇒ Array
NOTE: For now we only match on full names or first names.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/friends/friend.rb', line 120 def regexes_for_name # We generously allow any amount of whitespace between parts of a name. splitter = "\\s+" # Create the list of regexes and return it. chunks = name.split(Regexp.new(splitter)) # We check nicknames before first names because nicknames may contain # first names, as in "Amazing Grace" being a nickname for Grace Hopper. [ chunks, # Match a full name with the highest priority. *@nicknames.map { |n| [n] }, # Match a first name followed by a last name initial, period (that via # lookahead is *NOT* a part of an ellipsis), and then (via lookahead) # either: # - other punctuation that would indicate we want to swallow the period # (note that we do not include closing parentheses in this list because # they could be part of an offset sentence), OR # - anything, so long as the first alphabetical character afterwards is # lowercase. # This matches the "Jake E." part of something like "Jake E. and I went # skiing." or "Jake E., Marie Curie, and I studied science." This # allows us to correctly count the period as part of the name when it's # in the middle of a sentence. ( if chunks.size > 1 [chunks.first, "#{chunks.last[0]}\\.(?!\\.\\.)(?=([,!?;:—]+|(?-i)[^A-Z]+[a-z]))"] end ), # If the above doesn't match, we check for just the first name and then # a last name initial. This matches the "Jake E" part of something like # "I went skiing with Jake E." This allows us to correctly exclude the # period from the name when it's at the end of a sentence. ([chunks.first, chunks.last[0]] if chunks.size > 1), *(1..chunks.size - 1).map { |i| chunks.take(i) }.reverse ].compact.map do |words| Friends::RegexBuilder.regex(words.join(splitter)) end end |
#remove_nickname(nickname) ⇒ Object
89 90 91 92 93 94 95 |
# File 'lib/friends/friend.rb', line 89 def remove_nickname(nickname) unless @nicknames.include? nickname raise FriendsError, "Nickname \"#{nickname}\" not found for \"#{name}\"" end @nicknames.delete(nickname) end |
#remove_tag(tag) ⇒ Object
74 75 76 77 78 |
# File 'lib/friends/friend.rb', line 74 def remove_tag(tag) raise FriendsError, "Tag \"#{tag}\" not found for \"#{name}\"" unless @tags.include? tag @tags.delete(tag) end |
#serialize ⇒ String
Returns the file serialization text for the friend.
45 46 47 48 |
# File 'lib/friends/friend.rb', line 45 def serialize # Remove terminal effects for serialization. Paint.unpaint("#{SERIALIZATION_PREFIX}#{self}") end |
#to_s ⇒ String
Returns a string representing the friend’s name and nicknames.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/friends/friend.rb', line 51 def to_s unless @nicknames.empty? nickname_str = " (" + @nicknames.map do |nickname| "#{NICKNAME_PREFIX}#{Paint[nickname, :bold, :magenta]}" end.join(" ") + ")" end location_str = " [#{Paint[@location_name, :bold, :yellow]}]" unless @location_name.nil? tag_str = " #{Paint[@tags.join(' '), :bold, :cyan]}" unless @tags.empty? "#{Paint[@name, :bold]}#{nickname_str}#{location_str}#{tag_str}" end |