My favorites | Sign in
Project Home Wiki Issues
Brief instruction how to use this library
Featured, Phase-Implementation
Updated Feb 24, 2010 by macksx

See also:

Table of Contents


The gem is registered to a gem server, so that all you should do to install is to execute the following command:

 $ sudo gem install ruby_protobuf

Compile Your .proto File

 $ rprotoc PROTOFILE

When PROTOFILE is named 'person.proto,' the name of the generated ruby source is 'person.pb.rb.'

To know about other options, use -h option.

 $ rprotoc -h
    -p, --proto_path <PATH>          Specify the directory in which to search for imports. The current directory is default.
    -o, --out <OUT_DIR>              Specify the directory in which Ruby source file is generated. The current directory is default.
    -v, --version                    Show version.
    -h, --help                       Show this message.

Generated Ruby Code

A .proto file like this:

package tutorial;

message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];

  repeated PhoneNumber phone = 4;

  extensions 100 to 200;

extend Person {
  optional int32 age = 100;

message AddressBook {
  repeated Person person = 1;

generates ruby code like this:

module Tutorial
  class Person < ::Protobuf::Message
    required :string, :name, 1
    required :int32, :id, 2
    optional :string, :email, 3

    class PhoneType < ::Protobuf::Enum
      define :MOBILE, 0
      define :HOME, 1
      define :WORK, 2

    class PhoneNumber < ::Protobuf::Message
      required :string, :number, 1
      optional :PhoneType, :type, 2, :default => :HOME

    repeated :PhoneNumber, :phone, 4
    extensions 100..200

  class Person < ::Protobuf::Message
    optional :int32, :age, 100, :extension => true

  class AddressBook < ::Protobuf::Message
    repeated :Person, :person, 1

The Protocol Buffer API

As you can see in the previous section, messages and fields in a proto file is respectively converted to ruby classes derived from Protobuf::Message class and their attributes. Using the class and its instance, you could write:

require 'addressbook.pb'
include Tutorial
person = = 1234 = 'John Doe' = ''
phone =
phone.number = '555-4321'
phone.type = Person::PhoneType::HOME << phone

Note that the type of variable is checked in accordance with the proto file when assigned:

person.no_such_field = 1  # raises NoMethodError = '1234'        # raises TypeError


Enum field can accept integer value, symbol value or EnumValue object. On general case, you will use integers or symbols, and may not notice EnumValue object because EnumValue object is automatically converted into integer value.

For example, when .proto is:

enum EnumType {
  FIRST = 1;
  SECOND = 2;
message Message {
  required EnumType enum = 1;

generated code is:

class EnumType < ::Protobuf::Enum
  define :FIRST, 1
  define :SECOND, 2
class Message < ::Protobuf::Message
  required :EnumType, :enum, 1

and you can use like this:

EnumType::FIRST.class   #=> Protobuf::EnumValue
EnumType::FIRST == 1    #=> true
1 == EnumType::FIRST    #=> true

message =
message.enum = EnumType::FIRST  # OK
message.enum = 1                # OK
message.enum = :FIRST           # OK
message.enum.class              #=> Protobuf::EnumValue

puts "value is #{message.enum}"  #=> "value is FIRST"

Standard Message Methods

  • initialized? : checks if all the required fields have been set.
  • dup : duplicate the message.
  • clear! : clears all the elements back to the empty state.
  • has_field?(field_name) : checks a field value is already set or not. It's useful for optional fields.
  • inspect : returns a human-readable representation of the message.

Parsing and Serialization

Finally, each protocol buffer class has methods for writing and reading messages of your chosen type using the protocol buffer binary format. These include:

  • serialize_to_string : serializes the message and returns it as a string. Note that the bytes are binary, not text; we only use the str type as a convenient container.
  • to_s : alias of serialize_to_string.
  • serialize_to_file(filename)
  • serialize_to(stream)
  • parse_from_string(data) : parses a message from the given string.
  • parse_from_file(filename)
  • parse_from(stream)

Sample (Mini) Applications

Writing A Message



require 'addressbook.pb'

def prompt_for_address(person)
  print 'Enter person ID number: ' = STDIN.gets.strip.to_i
  print 'Enter name: ' = STDIN.gets.strip
  print 'Enter email address (blank for none): '
  email = STDIN.gets.strip = email unless email.empty?

  loop do
    print 'Enter a phone number (or leave blank to finish): '
    break if (number = STDIN.gets.strip).empty? << = number

    print 'Is this a mobile, home, or work phone? ' =
      case type = STDIN.gets.strip
      when 'mobile'
      when 'home'
      when 'work'
        puts 'Unknown phone type; leaving as default value.'

unless ARGV.size == 1
  puts "Usage: #{$0} ADDRESS_BOOK_FILE"

address_book =
address_book.parse_from_file ARGV[0] if File.exist? ARGV[0]
address_book.person <<
prompt_for_address address_book.person.last
address_book.serialize_to_file ARGV[0]

Reading A Message



require 'addressbook.pb'

def list_people(address_book)
  address_book.person.each do |person|
    puts "Person ID: #{}"
    puts "  Name: #{}"
    puts "  E-mail: #{}" unless do |phone_number|
      print(case phone_number.type
            when Tutorial::Person::PhoneType::MOBILE
              '  Mobile phone #: '
            when Tutorial::Person::PhoneType::HOME
              '  Home phone #: '
            when Tutorial::Person::PhoneType::WORK
              '  Work phone #: '
      puts phone_number.number

unless ARGV.size == 1
  puts "Usage: #{$0} ADDRESS_BOOK_FILE"

address_book =
address_book.parse_from_file ARGV[0]

list_people address_book
Comment by, Nov 20, 2008

I can successfully run the 'write' code the first time. When it tries to read from the file I just created, it blows up. Any idea what is causing this? I also tried manually creating an address book object (from the 'The Protocol Buffer API' section above) and it blew up the same way in the parse_from_file call.

gems/ruby_protobuf-0.3.0/lib/protobuf/message/field.rb:579:in `pack': pack(U): value out of range (RangeError?)

from gems/ruby_protobuf-0.3.0/lib/protobuf/message/field.rb:579:in `set_array' etc.

Comment by, Nov 26, 2008

I get the same thing.

Comment by, Dec 16, 2008

Does anyone know if this project is still being maintained?

Comment by project member, Dec 17, 2008

Comments are not notified. I read these comment just now. I'm grad if you add an issue when you find a bug.

Comment by project member, Dec 17, 2008

To pauljsolomon and snow.gregory,

How about 0.3.2? On my computer, it looks work.

$ cd examples 
$ RUBYLIB=../lib ruby writing_a_message.rb myaddr 
Enter person ID number: 123 
Enter name: yasushi 
Enter email address (blank for none): yasushi@ando 
Enter a phone number (or leave blank to finish): 321-123 
Is this a mobile, home, or work phone? mobile 
Enter a phone number (or leave blank to finish): 123-456 
Is this a mobile, home, or work phone? home 
Enter a phone number (or leave blank to finish): 
$ RUBYLIB=../lib ruby reading_a_message.rb myaddr 
Person ID: 123 
  Name: yasushi
  E-mail: yasushi@ando
  Mobile phone #: 321-123
  Home phone #: 123-456 
Comment by, Oct 26, 2009

I have done a comparison of reading 1 million json message and transform it into a protobuf object. That's about 5.5 times slower than reading the same 1 million json message, convert it to ruby hash, then convert the hash back to json message and output to file.

The json-to-ruby-to-json-plus-io is in theory doing more. The json-to-protobuf doesn't output the serialized stream yet. All it does is construct the protobuf data object.

Comment by, Dec 30, 2010


Can your Java app read in that Ruby hash? ;]

Comment by, Apr 9, 2011

Can I store multiple message in a single serialize_to_file?

Please advice me

Thanks Hussain

Sign in to add a comment
Powered by Google Project Hosting