Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions motion/core_ext/string/access.rb
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,33 @@ def last(limit = 1)
from(-limit)
end
end

# Emojis pose a problem for array-like access of a string. If you try to
# grab one register you'll get am error: "You can't cut a surrogate in two in
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "you'll get am error"

# an encoding that is not UTF-16 (IndexError)"
# Calling split(''), which splits the string into array of characters, works
# correctly even with emojis. So to make this method work as expected for
# strings, first split it then join.

# These are the method definitions of String#[]. The first three match the
# method definition of an array so only apply the patch if the arguments
# look like that.
# - str[index] => new_str or nil
# - str[start, length] => new_str or nil
# - str[range] => new_str or nil
# - str[regexp] => new_str or nil
# - str[regexp, capture] => new_str or nil
# - str[match_str] => new_str or nil
alias_method :bracket_access_original, :[]

def [](*args)
unless args[0].is_a?(Numeric) || args[0].is_a?(Range)
return bracket_access_original(*args)
end

# Could be nil, string (one character), or array of characters
characters = split('')[*args]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test for each of those three cases?


characters.is_a?(Array) ? characters.join : characters
end
end
5 changes: 5 additions & 0 deletions spec/motion-support/core_ext/string/access_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,10 @@
hash["hello123".first(5)] = true
hash.keys.should == %w(hello)
end

it "should handle emojis" do
"😊 hello"[0].should == "😊"
"😊 hello".last(5).should == "hello"
end
end
end