ProductPromotion
Logo

Elixir

made by https://0x3d.site

GitHub - gaynetdinov/ex_marshal: Ruby Marshal format implemented in Elixir
Ruby Marshal format implemented in Elixir. Contribute to gaynetdinov/ex_marshal development by creating an account on GitHub.
Visit Site

GitHub - gaynetdinov/ex_marshal: Ruby Marshal format implemented in Elixir

GitHub - gaynetdinov/ex_marshal: Ruby Marshal format implemented in Elixir

ExMarshal Build Status Hex pm

ExMarshal encodes and decodes Elixir terms according to Ruby Marshal format.

Currently supported Ruby types are nil, false, true, Fixnum, Bignum, BigDecimal, Float, Symbol, String, Array, Hash as well as user-defined types such as Date.

Why?

Once you decide to integrate small Elixir tool into big-old-legacy Ruby system, chances are that you need to interact with Memcached. As soon as Ruby code writes something into Memcached, most likely Ruby uses dalli gem. And Dalli uses Ruby Marshal by default.

Another use case is to decode Rails session encoded using Ruby Marshal. For this you can use plug_rails_cookie_session_store or plug_session_redis if you want to store session data in Redis.

Installation

Add ExMarshal as a dependency to your mix.exs file:

def deps do
  [{:ex_marshal, "0.0.13"}]
end

Usage

iex(1)> ExMarshal.decode(<<4, 8, 91, 8, 105, 6, 105, 7, 105, 8>>)
[1, 2, 3]
iex(2)> ExMarshal.encode([1, 2, 3])
<<4, 8, 91, 8, 105, 6, 105, 7, 105, 8>>
iex(3)>

It is also possible to decode user objects such as Ruby dates using custom parsers which can be specified via the user_object_parsers option:

iex(1)> value = <<4, 8, 85, 58, 9, 68, 97, 116, 101, 91, 11, 105, 0, 105, 3, 72, 136, 37, 105, 0, 105, 0, 105, 0, 102, 12, 50, 50, 57, 57, 49, 54, 49>>
<<4, 8, 85, 58, 9, 68, 97, 116, 101, 91, 11, 105, 0, 105, 3, 72, 136, 37, 105,
  0, 105, 0, 105, 0, 102, 12, 50, 50, 57, 57, 49, 54, 49>>
iex(2)> ExMarshal.decode(value, user_object_parsers: %{Date: fn [_, julian_day, _, _, _, _] -> Date.from_gregorian_days(julian_day - 1721425) end})
~D[2021-05-20]

Nullify Ruby Objects

The default behaviour of ExMarshal is to raise an error when trying to decode an serilized ruby object. This config option can be used to nullify the ruby object without raising an error:

config :ex_marshal,
  nullify_objects: true

Use Case Rails 3.2 puts Ruby Objects into session(i.e. Flash messages wrapped in an object). When Phoenix is trying to read Rails session, this will cause ExMarshal to raise an error and a 500 error in Phoenix. If you don't need to read these values from Elixir/Phoenix, this option allows ExMarshal to skip objects.

ExMarshal with Memcache.Client

One of the reasons why ExMarshal was created is to work with Memcached. Here is how ExMarshal can be used with Memcache.Client:


defmodule Memcache.Client.Transcoder.Ruby do
  @behaviour Memcache.Client.Transcoder

  @ruby_type_flag 0x0001

  def encode_value(value) do
    {ExMarshal.encode(value), @ruby_type_flag}
  end

  def decode_value(value, @ruby_type_flag) do
    ExMarshal.decode(value)
  end

  def decode_value(_value, data_type) do
    {:error, {:invalid_data_type, data_type}}
  end
end

Then tell Memcache.Client to use this transcoder:

config :memcache_client,
  transcoder: Memcache.Client.Transcoder.Ruby

Examples

Read

Ruby side

:1 > dc = Dalli::Client.new('localhost:11211')
:2 > dc.set("str", "hello elixir")
 => true

Elixir side

iex(1)> Memcache.Client.get("str")
%Memcache.Client.Response{cas: 184, data_type: 1, extras: <<0, 0, 0, 1>>,
 key: "", status: :ok, value: "hello elixir"}

Write

Elixir side

iex(1)> Memcache.Client.set("str", "hello ruby")
%Memcache.Client.Response{cas: 185, data_type: nil, extras: "", key: "",
 status: :ok, value: ""}

Ruby side

:1 > dc = Dalli::Client.new('localhost:11211')
:2 > dc.get("str")
 => "hello ruby"

Kudos

Thanks to @tsharju for ability to use custom transcoders in Memcache.Client

Thanks to @shepmaster for series of posts about Ruby Marshal format.

Special thanks to @lexmag for help in writing this tool and for guiding me through Elixir world.

License

This software is licensed under the ISC license.

Articles
to learn more about the elixir concepts.

Resources
which are currently available to browse on.

mail [email protected] to add your project or resources here 🔥.

FAQ's
to know more about the topic.

mail [email protected] to add your project or resources here 🔥.

Queries
or most google FAQ's about Elixir.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory