Ruby to Python conversion stuck on the equivalent - ruby

I'm converting a project from Ruby to Python. There is a force_encoding method used in Ruby. I'm stuck there not able to find anything equivalent in Python.
I've tried to use the encode method but it changes the representation of the string in memory itself.
callback = lambda do |context, kb, k|
yield(k.get_bytes(0, kb).force_encoding(encoding))
end

Related

Ruby Copy-on-Write: Why MRI Ruby string has a shared pointer to one string

I'm reading internal Ruby about how Ruby handles with string when copy.
str = "StackOverFlow"
ustr2 = str.dup
here is the image for JRuby when ustr2 is duplicated from str:
I can understand this. But below is the image of MRI Ruby interpreter:
The thing I don't know is: why both String should have shared pointer to another pointer points to that string. I think we only need pointer point to head of string. (In this case is character 'G').
Thanks
#Edit: This concept and those 2 illustrations I got from "Ruby under the Microscope" book.

Which method could I use to parse difficult string?

I do a mysql query in ruby, and it gives me a string like that:
O:8:"stdClass":4:{s:7:"updates";a:1:{i:0;O:8:"stdClass":10:{s:8:"response";s:6:"latest";s:8:"download";s:65:"https://downloads.wordpress.org/release/fr_FR/wordpress-4.2.4.zip";s:6:"locale";s:5:"fr_FR";s:8:"packages";O:8:"stdClass":5:{s:4:"full";s:65:"https://downloads.wordpress.org/release/fr_FR/wordpress-4.2.4.zip";s:10:"no_content";b:0;s:11:"new_bundled";b:0;s:7:"partial";b:0;s:8:"rollback";b:0;}s:7:"current";s:5:"4.2.4";s:7:"version";s:5:"4.2.4";s:11:"php_version";s:5:"5.2.4";s:13:"mysql_version";s:3:"5.0";s:11:"new_bundled";s:3:"4.1";s:15:"partial_version";s:0:"";}}s:12:"last_checked";i:1439805713;s:15:"version_checked";s:5:"4.2.4";s:12:"translations";a:0:{}}
I need to parse this part: s:6:"latest" to know if it's the latest version or an upgrade is available.
Which method could I use to do it in ruby? I just started this language and it's my first object oriented language, I only do C habitually.
This is string serialized with PHP. There is no simple, and stable way to parse that in Ruby. Regular expressions will get you only so far and will be fragile, since the serialized string is not regular.
There is, however, a gem php-serialize that allows unserialize and serialize in the PHP-way from Ruby. If you look into the gem, you'll see how complex the parser really is.
With that gem you could do:
require 'php-serialize'
string = 'O:8:"stdClass":4:{s:7:"updates";a:1:{i:0;O:8:"stdClass":10:{s:8:"response";s:6:"latest";s:8:"download";s:65:"https://downloads.wordpress.org/release/fr_FR/wordpress-4.2.4.zip";s:6:"locale";s:5:"fr_FR";s:8:"packages";O:8:"stdClass":5:{s:4:"full";s:65:"https://downloads.wordpress.org/release/fr_FR/wordpress-4.2.4.zip";s:10:"no_content";b:0;s:11:"new_bundled";b:0;s:7:"partial";b:0;s:8:"rollback";b:0;}s:7:"current";s:5:"4.2.4";s:7:"version";s:5:"4.2.4";s:11:"php_version";s:5:"5.2.4";s:13:"mysql_version";s:3:"5.0";s:11:"new_bundled";s:3:"4.1";s:15:"partial_version";s:0:"";}}s:12:"last_checked";i:1439805713;s:15:"version_checked";s:5:"4.2.4";s:12:"translations";a:0:{}}'
wp_settings = PHP.unserialize(string)
puts wp_settings.updates.inspect

Prettyprint a ruby hash to erlang term format

I am trying to write a configuration file for an erlang application (rabbitmq) whose conf si written as an erlang term 1.
My attribute is a ruby hash, do you know how I can convert this hash to a pretty printed erlang term ?
If I had to do this on my own, maybe something like:
def to_erl(o)
case o
when Hash
'[' +
o.map {|(k,v)|
"{#{k}, #{to_erl v}}"
}.join(",\n") +
']'
when Array
'[' + o.map{|v| to_erl(v)}.join(",") +']'
when TrueClass then "true"
when FalseClass then "false"
when Integer then o.to_s
when String then o
when Symbol then o.to_s
# ... and whatever else you can think of
else
raise "Don't know how to erlify #{o}"
end
end
... But I bet there's some nice code you can steal off of some
open source project that has to serialize between ruby and erlang.
For serialization to erlang, BERT is the defacto (Binary Erlang terms).
There's lots of libraries that go from Ruby hashes to BERT, it seems.
Haven't seen one that gives you plain textual erlang terms.
Since this is for a chef recipe, it's a good idea not to mess with
too many ruby dependencies at converge time. You'll be calling #to_hash
on your chef attributes, and what you will get back will straight-forward
enough (no objects, just number/bools/strings/arrays and hashes I guess)
to manage with a bit of home grown code.

Rubinius: how to generate enumerator as the official way?

I have this simple code to generate a lazy array:
lazy_arr = Enumerator.new { |y|
i = 1
loop {
y << i
i+=1
}
}
p lazy_arr.take(5)
In official Ruby 1.9.3, the output is [1,2,3,4,5], which is what I want.
But in Rubinius, it gives error and tells me cannot find Enumerator constant.
So I looked it up, and find Enumerator defined in Enumerable module instead of kernel, and when it is generated, it needs a few arguments in the brackets:
http://rubydoc.info/github/evanphx/rubinius/master/Enumerable/Enumerator
I tried to change Enumerator.new to Enumerable::Enumerator.new, or include Enumerable, neither works because it needs more arguments.
How can I do the example above in Rubinius? Is there any way around to make the code work in both official and Rubinius?
You're using Rubinius in 1.8 mode, which doesn't have Enumerator in the global namespace. Please use Rubinius in 1.9 mode and the example works fine then. You can use 1.9 by passing -X19 when starting Rubinius, or setting RBXOPT=-X19 for example.
It's also possible to make 1.9 mode the default with configure during compile time.
Sounds like a bug/missing class in Rubinius. Open up an issue on github and it will get added. Or dig in and send a pull request!

How can I splattify an anonymous object so I can use &method on it?

I'm wanting to use the &method(:method_name) idiom when there's more than one object required by method_name. Can I do this under Ruby 1.9?
For example, if I've got
def move_file(old_filename, new_filename)
STDERR.puts "Moving #{old_filename.inspect} to #{new_filename.inspect}"
# Implementation for careful moving goes here
end
old_filenames = ["foo.txt", "bar.txt", "hoge.ja.txt"]
new_filenames = ["foo_20110915.txt", "bar_20110915.txt", "hoge_20110915.ja.txt"]
the code
old_filenames.zip(new_filenames).each(&method(:move_file))
works under Ruby 1.8, but not under Ruby 1.9. Under Ruby 1.9, it's trying to do move_file(["foo.txt", "foo_20110915.txt"]) instead of move_file("foo.txt", "foo_20110915.txt").
How do I splattify it so it has the correct arity?
Workarounds I'm aware of:
Replace def move_file(old_filename, new_filename) with def move_file(*arguments)
Replace each(&method(:move_file)) with
each{|old_filename, new_filename| move_file(old_filename, new_filename)}
Instead
each{|old_filename, new_filename| move_file(old_filename, new_filename)}
you should be able to do
each{|pair| move_file(*pair)}
But I don't know how you'd pull off blockless variant (I needed it couple of times as well). I guess &-shorthand was made to make the syntax simpler, and is not meant to be clogged much (whether it will be passed an array as an array, or splatted, for example). :)
How do I splattify it so it has the correct arity?
I don't think there is a way to do this while being compatible to both Ruby versions. What you could do is wrap it into a lambda
move_from_to = Proc.new {|*both| move_files(*both) }
The thing is - block and proc arity is something that got addressed in Ruby 1.9 so there might be a difference in behavior there. Also see prc.lambda? here http://www.ruby-doc.org/core/classes/Proc.html for info on what it does to the arity.
This question is also related to what you want to do (the solution there is to resplat and unsplat manually): Inconsistency of arity between Hash.each and lambdas

Resources