1This directory contains the Ruby extension that implements Protocol Buffers 2functionality in Ruby. 3 4The Ruby extension makes use of generated Ruby code that defines message and 5enum types in a Ruby DSL. You may write definitions in this DSL directly, but we 6recommend using protoc's Ruby generation support with .proto files. The build 7process in this directory only installs the extension; you need to install 8protoc as well to have Ruby code generation functionality. You can build protoc 9from source using `bazel build //:protoc`. 10 11Installation from Gem 12--------------------- 13In Gemfile (Please check which version of Protocol Buffers you need: [RubyGems](https://rubygems.org/gems/google-protobuf)): 14 15 gem 'google-protobuf' 16 17Or for using this pre-packaged gem, simply install it as you would any other gem: 18 19 $ gem install [--prerelease] google-protobuf 20 21Once the gem is installed, you may or may not need `protoc`. If you write your 22message type descriptions directly in the Ruby DSL, you do not need it. 23However, if you wish to generate the Ruby DSL from a `.proto` file, you will 24also want to install Protocol Buffers itself, as described in this repository's 25main `README` file. The version of `protoc` included in the latest release 26supports the `--ruby_out` option to generate Ruby code. 27 28A simple example of using the Ruby extension follows. More extensive 29documentation may be found in the RubyDoc comments (`call-seq` tags) in the 30source, and we plan to release separate, more detailed, documentation at a 31later date. 32 33```ruby 34require 'google/protobuf' 35 36# generated from my_proto_types.proto with protoc: 37# $ protoc --ruby_out=. my_proto_types.proto 38require 'my_proto_types' 39 40mymessage = MyTestMessage.new(:field1 => 42, :field2 => ["a", "b", "c"]) 41mymessage.field1 = 43 42mymessage.field2.push("d") 43mymessage.field3 = SubMessage.new(:foo => 100) 44 45encoded_data = MyTestMessage.encode(mymessage) 46decoded = MyTestMessage.decode(encoded_data) 47assert_equal mymessage, decoded 48puts "JSON:" 49puts MyTestMessage.encode_json(mymessage) 50``` 51 52Installation from Source (Building Gem) 53--------------------------------------- 54 55 56Protocol Buffers has a new experimental backend that uses the 57[ffi](https://github.com/ffi/ffi) gem to provide a unified C-based 58implementation across Ruby interpreters based on 59[UPB](https://github.com/protocolbuffers/upb). For now, use of the FFI 60implementation is opt-in. If any of the following are true, the traditional 61platform-native implementations (MRI-ruby based on CRuby, Java based on JRuby) 62are used instead of the new FFI-based implementation: 1. `ffi` and 63`ffi-compiler` gems are not installed 2. `PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION` 64environment variable has a value other than `FFI` (case-insensitive). 3. FFI is 65unable to load the native library at runtime. 66 67To build this Ruby extension, you will need: 68 69* Rake 70* Bundler 71* Ruby development headers 72* a C compiler 73 74To Build the JRuby extension, you will need: 75 76* Maven 77* The latest version of the protobuf java library (see ../java/README.md) 78* Install JRuby via rbenv or RVM 79 80First switch to the desired platform with rbenv or RVM. 81 82Then install the required Ruby gems: 83 84 $ gem install bundler 85 $ bundle 86 87Then build the Gem: 88 89 $ rake 90 $ rake clobber_package gem 91 $ gem install `ls pkg/google-protobuf-*.gem` 92 93To run the specs: 94 95 $ rake test 96 97To run the specs while using the FFI-based implementation: 98 99``` 100$ PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION=FFI rake test 101``` 102 103This gem includes the upb parsing and serialization library as a single-file 104amalgamation. It is up-to-date with upb git commit 105`535bc2fe2f2b467f59347ffc9449e11e47791257`. 106 107Alternatively, you can use Bazel to build and to run tests. 108 109From the project root (rather than the `ruby` directory): 110 111``` 112$ bazel test //ruby/tests/... 113``` 114 115To run tests against the FFI implementation: 116 117``` 118$ bazel test //ruby/tests/... //ruby:ffi_enabled --test_env=PROTOCOL_BUFFERS_RUBY_IMPLEMENTATION=FFI 119``` 120 121Version Number Scheme 122--------------------- 123 124We are using a version number scheme that is a hybrid of Protocol Buffers' 125overall version number and some Ruby-specific rules. Gem does not allow 126re-uploads of a gem with the same version number, so we add a sequence number 127("upload version") to the version. We also format alphabetical tags (alpha, 128pre, ...) slightly differently, and we avoid hyphens. In more detail: 129 130* First, we determine the prefix: a Protocol Buffers version "3.0.0-alpha-2" 131 becomes "3.0.0.alpha.2". When we release 3.0.0, this prefix will be simply 132 "3.0.0". 133* We then append the upload version: "3.0.0.alpha.2.0" or "3.0.0.0". If we need 134 to upload a new version of the gem to fix an issue, the version becomes 135 "3.0.0.alpha.2.1" or "3.0.0.1". 136* If we are working on a prerelease version, we append a prerelease tag: 137 "3.0.0.alpha.3.0.pre". The prerelease tag comes at the end so that when 138 version numbers are sorted, any prerelease builds are ordered between the 139 prior version and current version. 140 141These rules are designed to work with the sorting rules for 142[Gem::Version](http://ruby-doc.org/stdlib-2.0/libdoc/rubygems/rdoc/Gem/Version.html): 143release numbers should sort in actual release order. 144