Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up dynamic code generation in prep for extension namespacing #302

Merged
merged 1 commit into from
Feb 24, 2016

Conversation

embark
Copy link
Contributor

@embark embark commented Feb 12, 2016

@embark embark force-pushed the fix-setters-and-getters branch 2 times, most recently from 7d8247e to 133207b Compare February 12, 2016 01:51
if field.repeated?
if value.is_a?(Array)
value = value.dup
value.compact!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is preserving existing behavior, but just want to note that IMO this compact thing is super weird behavior, settings an array with nil values in there should def be an error

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're going to keep compact!, you should remove the dup and just do value = value.compact. You can drop an array iteration that way and get the same behavior.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Note though: We copied the code over with minimal changes. No objection to cleaning as we go though.

@zachmargolis
Copy link
Contributor

Should we add a test that verified that the fully qualified names are properly used as keys in @values to make sure they are set correctly?

when optional? then typed_default_value
when repeated? then ::Protobuf::Field::FieldArray.new(self).freeze
when required? then nil
@default_value ||= if optional? || required?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't adding required? unnecessary because required? should always have a value.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol, ya, but protoc allows default values on required fields, sooooo... we should handle it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol welp

@embark
Copy link
Contributor Author

embark commented Feb 12, 2016

re: #302 (comment)

We don't yet actually use fully qualified names, but there's a PR incoming where we will add a test for it

@embark embark force-pushed the fix-setters-and-getters branch from 133207b to b0f62ba Compare February 12, 2016 21:38
elsif repeated?
::Protobuf::Field::FieldArray.new(self).freeze
else
fail "something went very wrong"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe something like "unable to produce default value" or something? very ominous message

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well this code should be unreachable actually, so it should be ominous -- it means a field isn't optional, required, or repeated. We could make change the message though to still be ominous while more descriptive :)

@embark embark force-pushed the fix-setters-and-getters branch 2 times, most recently from 065400e to 49412d1 Compare February 15, 2016 21:56
@embark
Copy link
Contributor Author

embark commented Feb 16, 2016

All comments are addressed, interested in review by someone with write access to the repo :)

@embark embark force-pushed the fix-setters-and-getters branch from 49412d1 to 3176340 Compare February 17, 2016 19:04
@embark embark force-pushed the fix-setters-and-getters branch from 3176340 to 10c3ea1 Compare February 17, 2016 19:06
@embark embark closed this Feb 22, 2016
@embark embark reopened this Feb 22, 2016
@nerdrew nerdrew force-pushed the fix-setters-and-getters branch from 10c3ea1 to 4b85f47 Compare February 23, 2016 17:31
@embark embark force-pushed the fix-setters-and-getters branch from 4b85f47 to 10c3ea1 Compare February 23, 2016 17:34
@nerdrew nerdrew force-pushed the fix-setters-and-getters branch from 10c3ea1 to 1ceee2f Compare February 23, 2016 17:37
@embark
Copy link
Contributor Author

embark commented Feb 23, 2016

Hey all, I'm looking for reviews from some people with write access because there will be a few commits following up to this with the goal of adding custom option support to the gem. Pinging a couple people who have merged recently (many apologies for the noise).

CC @film42 @liveh2o

@@ -122,10 +124,10 @@ def required?

# FIXME: need to cleanup (rename) this warthog of a method.
def set(message_instance, bytes)
return message_instance.__send__(setter, decode(bytes)) unless repeated?
return message_instance.__send__(getter) << decode(bytes) unless packed?
return message_instance[name] = decode(bytes) unless repeated?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this still flow through the setter? I'm exactly sure why we needed to be calling the setter here, but I want to make sure this isn't unintentionally altering behavior.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Though perhaps that is the point here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The []= method now is the setter and [] is now the getter, so it should be the same. The old setter and getter still exist for runtime access of the proto, but they alias to the former two methods now.

For just a little more background, [] and []= used to alias to the setter and getter instead, but we switched that around so that we didn't have this weird dynamic usage of the setters and getters.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. No more __send__(xxx).

@brianstien
Copy link
Contributor

@embark I don't have write access, but for any reviewers that do, I reviewed this and 👍.

Flipping around the [], []= with the setters makes the internals easier to read. I also like using the coerce! interface instead of overriding the define_setter method.

@film42
Copy link
Member

film42 commented Feb 23, 2016

Just remove the @encode and I'll cut a release. Thank you for your contribution! :)

@embark embark force-pushed the fix-setters-and-getters branch from 1ceee2f to ad05d79 Compare February 23, 2016 20:28
@nerdrew nerdrew force-pushed the fix-setters-and-getters branch from ad05d79 to 1ceee2f Compare February 23, 2016 20:30
@embark embark force-pushed the fix-setters-and-getters branch from 1ceee2f to 154fbad Compare February 23, 2016 20:32
@embark
Copy link
Contributor Author

embark commented Feb 23, 2016

Many thanks to all the reviews and responses! -- Removed @encode so all should be well

@embark
Copy link
Contributor Author

embark commented Feb 23, 2016

CC @film42 all green!

@film42
Copy link
Member

film42 commented Feb 24, 2016

:shipit:

film42 added a commit that referenced this pull request Feb 24, 2016
Clean up dynamic code generation in prep for extension namespacing
@film42 film42 merged commit 757068b into ruby-protobuf:master Feb 24, 2016
@film42
Copy link
Member

film42 commented Feb 24, 2016

Hmm. I used to have push access to rubygems.. looks like someone is going to need to add me again. Tomorrow I'll cut this as 3.7.0.pre0.

@embark
Copy link
Contributor Author

embark commented Feb 24, 2016

@film42 Thanks! There will be a few PRs to come to get support for custom options if you want to wait for that before cutting a new release, though it's up to you.

@embark embark deleted the fix-setters-and-getters branch February 24, 2016 06:52
@embark
Copy link
Contributor Author

embark commented Mar 2, 2016

FYI @film42 @liveh2o @zachmargolis @nerdrew I just discovered that this PR changed the behavior of the []= setter to be correct in the case when nil is passed to it as a value.

Old behavior for repeated fields:

% pry(main)> message = ::Test::TestMessage.new(repeated: [1,2])
=> #<Test::TestMessage repeated =[1, 2]>

% pry(main)> message['repeated'] = nil
=> nil

% pry(main)> message
=> #<Test::TestMessage repeated =[1, 2]>

note that nothing happens when nil is passed in.

New behavior for repeated fields:

% pry(main)> message['repeated'] = ::Test::TestMessage.new(repeated: [1,2])
=> #<Test::TestMessage repeated =[1, 2]>

% pry(main)> message['repeated'] = nil
TypeError:                 Expected repeated value of type 'Protobuf::Field::Int32Field'
                Got 'NilClass' for repeated protobuf field rep

% pry(main)> message
=> #<Test::TestMessage rep=[1, 2]>

Old behavior for optional fields:

% pry(main)> message = ::Test::TestMessage.new(optional: 1)
=> #<Test::TestMessage optional = 1>

% pry(main)> message['optional'] = nil
=> nil

% pry(main)> message
=> #<Test::TestMessage optional = 1>

again, nothing happens to the field, it isn't even cleared.

New behavior for optional fields:

% pry(main)> message = ::Test::TestMessage.new(optional: 1)
=> #<Test::TestMessage optional = 1>

% pry(main)> message['optional'] = nil
=> nil

% pry(main)> message
=> #<Test::TestMessage optional = 0>

now the optional field has been cleared.

NOTE: the new []= behavior now matches the behavior of the dynamically defined setters (e.g. message.repeated and message.optional). It was a bug to silently do nothing in the []= setter when nil was passed in.

embark pushed a commit to nerdrew/protobuf-gem that referenced this pull request Mar 2, 2016
…ters

Clean up dynamic code generation in prep for extension namespacing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants