Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

don't create the RepeatedField until it is accessed

  • Loading branch information...
commit 7f40cbdbc767a20e4e00d8332f1e12230e432d7b 1 parent da767f8
Brian Palmer codekitchen authored
84 lib/protocol_buffers/runtime/field.rb
View
@@ -121,57 +121,73 @@ def initialize(otype, name, tag, opts = {})
end
def add_reader_to(klass)
- klass.class_eval <<-EOF, __FILE__, __LINE__+1
- def #{name}
- if @set_fields[#{tag}] == nil
- # first access of this field, generate it
- initialize_field(#{tag})
+ if repeated?
+ klass.class_eval <<-EOF, __FILE__, __LINE__+1
+ def #{name}
+ unless @#{name}
+ @#{name} = RepeatedField.new(fields[#{tag}])
+ end
+ @#{name}
end
- @#{name}
- end
- EOF
- end
-
- def add_writer_to(klass)
- klass.class_eval <<-EOF, __FILE__, __LINE__+1
- def #{name}=(value)
- field = fields[#{tag}]
- if value.nil?
- @set_fields[#{tag}] = false
- @#{name} = field.default_value
- else
- field.check_valid(value)
- @set_fields[#{tag}] = true
- @#{name} = value
- if @parent_for_notify
- @parent_for_notify.default_changed(@tag_for_notify)
- @parent_for_notify = @tag_for_notify = nil
- end
+ EOF
+ else
+ klass.class_eval <<-EOF, __FILE__, __LINE__+1
+ def #{name}
+ if @set_fields[#{tag}] == nil
+ # first access of this field, generate it
+ initialize_field(#{tag})
end
+ @#{name}
end
- EOF
+ EOF
+ end
end
- def add_methods_to(klass)
+ def add_writer_to(klass)
if repeated?
klass.class_eval <<-EOF, __FILE__, __LINE__+1
- attr_reader :#{name}
-
def #{name}=(value)
if value.nil?
- @#{name}.clear
+ #{name}.clear
else
- @#{name}.clear
+ #{name}.clear
value.each { |i| @#{name}.push i }
end
end
+ EOF
+ else
+ klass.class_eval <<-EOF, __FILE__, __LINE__+1
+ def #{name}=(value)
+ field = fields[#{tag}]
+ if value.nil?
+ @set_fields[#{tag}] = false
+ @#{name} = field.default_value
+ else
+ field.check_valid(value)
+ @set_fields[#{tag}] = true
+ @#{name} = value
+ if @parent_for_notify
+ @parent_for_notify.default_changed(@tag_for_notify)
+ @parent_for_notify = @tag_for_notify = nil
+ end
+ end
+ end
+ EOF
+ end
+ end
+
+ def add_methods_to(klass)
+ add_reader_to(klass)
+ add_writer_to(klass)
+ if repeated?
+ # repeated fields are always "set"
+ klass.initial_set_fields[tag] = true
+
+ klass.class_eval <<-EOF, __FILE__, __LINE__+1
def has_#{name}?; true; end
EOF
else
- add_reader_to(klass)
- add_writer_to(klass)
-
klass.class_eval <<-EOF, __FILE__, __LINE__+1
def has_#{name}?
value_for_tag?(#{tag})
15 lib/protocol_buffers/runtime/message.rb
View
@@ -232,16 +232,7 @@ class Message
# message = MyMessageClass.new
# message.attributes = attributes
def initialize(attributes = {})
- @set_fields = []
- fields.each do |tag, field|
- # repeated fields are always "set"
- if field.repeated?
- @set_fields[tag] = true
- # TODO: it seems a shame to do this on every object initialization,
- # even if the repeated fields are never accessed
- self.instance_variable_set("@#{field.name}", RepeatedField.new(field))
- end
- end
+ @set_fields = self.class.initial_set_fields.dup
self.attributes = attributes
end
@@ -348,6 +339,10 @@ def self.fields
@fields || @fields = {}
end
+ def self.initial_set_fields
+ @set_fields ||= []
+ end
+
# Returns a hash of { tag => ProtocolBuffers::Field }
def fields
self.class.fields
Please sign in to comment.
Something went wrong with that request. Please try again.