diff --git a/src/bindings/ruby/lib/hammer.rb b/src/bindings/ruby/lib/hammer.rb
index 2032b36afbaa54841822802295a9799753ad199e..54b2501c71bd21bcae02b44977c9ea7e70e625fb 100644
--- a/src/bindings/ruby/lib/hammer.rb
+++ b/src/bindings/ruby/lib/hammer.rb
@@ -12,7 +12,7 @@ require 'hammer/parser_builder'
 
 parser = Hammer::Parser.build do
   token 'blah'
-  ch 'a'
+  ch 'a'.ord
   choice {
     sequence {
       token 'abc'
@@ -57,3 +57,17 @@ parser = h.token(s)
 p parser.parse 'BLAH' # => false
 s.upcase!
 p parser.parse 'BLAH' # => false
+
+
+x = nil
+parser = Hammer::Parser.build {
+  token 'abc'
+  x = indirect
+  end_p
+}
+x.bind(h.token('abd'))
+
+p parser.parse 'abcabdabd'
+p parser.parse 'abcabd'
+p parser.parse 'abdabd'
+p parser.parse 'abd'
diff --git a/src/bindings/ruby/lib/hammer/parser.rb b/src/bindings/ruby/lib/hammer/parser.rb
index 12d047629308e5546bb1da9fa6cfc781d84a7349..8ae6ee8bf5586ab65c7def6a1e856259757828ec 100644
--- a/src/bindings/ruby/lib/hammer/parser.rb
+++ b/src/bindings/ruby/lib/hammer/parser.rb
@@ -3,9 +3,22 @@ module Hammer
 
     # Don't create new instances with Hammer::Parser.new,
     # use the constructor methods instead (i.e. Hammer::Parser.int64 etc.)
-    def initialize
+    #
+    # name: Name of the parser. Should be a symbol.
+    # h_parser: The pointer to the parser as returned by hammer.
+    # dont_gc: Pass additional data that's used by the parser and needs to be saved from the garbage collector.
+    def initialize(name, h_parser, dont_gc)
+      @name = name
+      @h_parser = h_parser
+      @dont_gc = dont_gc
     end
 
+    attr_reader :name
+    attr_reader :h_parser
+
+    # Parse the given data. Returns true if successful, false otherwise.
+    #
+    # data: A string containing the data to parse.
     def parse(data)
       raise RuntimeError, '@h_parser is nil' if @h_parser.nil?
       raise ArgumentError, 'expecting a String' unless data.is_a? String # TODO: Not needed, FFI checks that.
@@ -16,24 +29,24 @@ module Hammer
       !result.null?
     end
 
+    # Binds an indirect parser.
+    def bind(other_parser)
+      raise RuntimeError, 'can only bind indirect parsers' unless self.name == :indirect
+      Hammer::Internal.h_bind_indirect(self.h_parser, other_parser.h_parser)
+    end
+
     def self.token(string)
       h_string = string.dup
       h_parser = Hammer::Internal.h_token(h_string, h_string.length)
 
-      parser = Hammer::Parser.new
-      parser.instance_variable_set :@h_parser, h_parser
-      # prevent string from getting garbage-collected
-      parser.instance_variable_set :@h_string, h_string
-      return parser
+      return Hammer::Parser.new(:token, h_parser, h_string)
     end
 
     def self.ch(num)
-      raise ArgumentError, 'expecting a Fixnum in 0..255', unless num.is_a?(Fixnum) and num.between?(0, 255)
+      raise ArgumentError, 'expecting a Fixnum in 0..255' unless num.is_a?(Fixnum) and num.between?(0, 255)
       h_parser = Hammer::Internal.h_ch(num)
 
-      parser = Hammer::Parser.new
-      parser.instance_variable_set :@h_parser, h_parser
-      return parser
+      return Hammer::Parser.new(:ch, h_parser, nil)
     end
 
     # Defines a parser constructor with the given name.
@@ -41,7 +54,7 @@ module Hammer
     #   hammer_function: name of the hammer function to call (default: 'h_'+name)
     #   varargs: Whether the function is taking a variable number of arguments (default: false)
     def self.define_parser(name, options = {})
-      hammer_function = options[:hammer_function] || ('h_' + name.to_s)
+      hammer_function = options[:hammer_function] || ('h_' + name.to_s).to_sym
       varargs = options[:varargs] || false
 
       # Define a new class method
@@ -54,10 +67,7 @@ module Hammer
         end
         h_parser = Hammer::Internal.send hammer_function, *args
 
-        parser = Hammer::Parser.new
-        parser.instance_variable_set :@h_parser, h_parser
-        parser.instance_variable_set :@sub_parsers, parsers # store sub parsers to prevent them from being garbage-collected
-        return parser
+        return Hammer::Parser.new(name, h_parser, parsers)
       end
     end
     private_class_method :define_parser
@@ -77,8 +87,8 @@ module Hammer
     define_parser :left
     define_parser :right
     define_parser :middle
-    define_parser :end
-    define_parser :nothing
+    define_parser :end_p
+    define_parser :nothing_p
     define_parser :butnot
     define_parser :difference
     define_parser :xor
@@ -92,10 +102,7 @@ module Hammer
     define_parser :length_value
     define_parser :and
     define_parser :not
-
-    # TODO: If indirect, add a bind method that calls h_bind_indirect
     define_parser :indirect
 
-    attr_reader :h_parser
   end
 end
diff --git a/src/bindings/ruby/lib/hammer/parser_builder.rb b/src/bindings/ruby/lib/hammer/parser_builder.rb
index d1618c51860ffd882294b55e3a6d9348eb865873..d610db9cec397c475fbcd939c90f61de74a2ab94 100644
--- a/src/bindings/ruby/lib/hammer/parser_builder.rb
+++ b/src/bindings/ruby/lib/hammer/parser_builder.rb
@@ -75,8 +75,8 @@ module Hammer
     define_parser :left
     define_parser :right
     define_parser :middle
-    define_parser :end
-    define_parser :nothing
+    define_parser :end_p
+    define_parser :nothing_p
     define_parser :butnot
     define_parser :difference
     define_parser :xor
@@ -90,7 +90,25 @@ module Hammer
     define_parser :length_value
     define_parser :and
     define_parser :not
-    define_parser :indirect
+
+    # At least indirect must return the parser instead of the builder, so it can be stored in a variable.
+    # Other possible solution:
+    #   Make indirect take a name parameter, and use the name to bind it later.
+    #   Example:
+    #     p = Hammer::Parser.build { indirect(:the_name) }
+    #     p.bind(:the_name, inner_parser)
+    #   (store names and parsers in hash in the builder,
+    #    when building merge hashes from sub builders and store everything in the resulting sequence or choice.
+    #    make Parser#bind take and optional symbol. if it is given, the name is looked up in the table.)
+    # TODO:
+    #   Think about this more.
+    #   Do we need to be able to build parsers by chaining function calls? DSL should be sufficient.
+    #   If yes, the parser methods in this class should not return "self", but the Hammer::Parser object they create.
+    def indirect
+      parser = Hammer::Parser.indirect
+      @parsers << parser
+      return parser
+    end
 
   end # class ParserBuilder