-
Notifications
You must be signed in to change notification settings - Fork 184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A minimal implementation of part 2 : msgpack #6
Conversation
This is very close to what I did as a rough sketch when writing the exercise, good work! Enumerator was a huge help here, it'll be interesting to see if someone submits a solution that does not use it so we can compare. |
* UTF-8 is the chosen encoding for the 'str' type
Thanks, indeed I missed to convert to UTF-8 if not already the case in |
It is not correct to use the "Ĕ".unpack("U*") # => [276] 276 is not representable as a single byte (it actually is the first UTF-8 codepoint of that string). |
@eregon: Hmm... I didn't realize that's what it would do, I guess I had assumed it'd handle multibyte sequences rather than requiring conversion to codepoints but that's clearly not the case. So what's the right way to solve this? |
When going from MessagePack to Ruby, It appears like we can use >> "Ĕ".bytes
=> [196, 148]
>> x = "".b
=> ""
>> x << 196
=> "\xC4"
>> x << 148
=> "\xC4\x94"
>> x.encode("UTF-8")
Encoding::UndefinedConversionError: "\xC4" from ASCII-8BIT to UTF-8
from (irb):44:in `encode'
from (irb):44
from /Users/seacreature/.rubies/ruby-2.1.1/bin/irb:11:in `<main>'
>> x.force_encoding("UTF-8")
=> "Ĕ" |
Indeed, When going to bytes, the obvious choice is |
OK, I think this is how I'm going to proceed in my own solution then. thanks! As for the rather annoying thing with getting the next N elements from an |
Yeah, I expected as well |
I also tried Here's a hack I built that works around the problem: class PersistentEnumerable
def initialize(collection)
@collection = collection
end
def each
counter = -1
Enumerator.new do |y|
loop do
counter += 1
break if counter == @collection.length
y.yield(@collection[counter])
end
end
end
end
pe = PersistentEnumerable.new([1,3,5,7,9,11])
enum = pe.each
p enum.take(2) #=> [1, 3]
p enum.take(2) #=> [5, 7]
# create a new closure
enum = pe.each
p enum.take(2) #=> [1,3] Relying on storing state in closures is a little scary, but it works! |
Note my original |
Neat, quite similar to what I was thinking! class Enumerator
def to_persistent
enum = rewind
Enumerator.new do |y|
loop { y << enum.next }
end
end
end |
Just enough to pass the given tests, yet considering the extension to multiple extended types.
The Hash type is certainly the most interesting one to pack/unpack.
And the use of the Enumerator feels definitely as the best way considering we never need to go back.