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

Add method to safely get or check the existence of attributes #796

Merged
merged 2 commits into from
Apr 22, 2016

Conversation

mcquin
Copy link
Contributor

@mcquin mcquin commented Apr 13, 2016

Resolves #794 by extending the attribute? and get_attribute DSL methods to apply to sub-attributes. Attributes can be specified as a /-delimited string, a list of string keys, a list of symbol keys, or a combination thereof.

Open to suggestions like:

  1. Only supporting a list of strings and symbols (get rid of that /-delimiter stuff, that's too fancy)
  2. Adding similar support to set_attribute in this PR (was gonna do it separate since the implementation is different).
  3. ___________________________________________________________________________.

@thommay
Copy link
Contributor

thommay commented Apr 13, 2016

🎉 👏 👍

@mcquin
Copy link
Contributor Author

mcquin commented Apr 13, 2016

@thommay minor change to require at least one parameter (o/w attribute? returns true and get_attribute returns all attributes and that would just be not good).

@tas50
Copy link
Contributor

tas50 commented Apr 13, 2016

+1 :shipit:

@mcquin
Copy link
Contributor Author

mcquin commented Apr 13, 2016

Thoughts from @chef/client-core ? :)

@thommay
Copy link
Contributor

thommay commented Apr 13, 2016

@mcquin good catch!

@jaymzh
Copy link
Collaborator

jaymzh commented Apr 13, 2016

Hmm. Should we instead try to make this match with the way we did node.rm? (which is node.rm('foo', 'bar')? i.e, take a list? What happens if I have an attribute with a slash in it (which is common in, say, the filesystem plugin).

I like the idea... but I don't dig the implementation.

@mcquin
Copy link
Contributor Author

mcquin commented Apr 13, 2016

@jaymzh whoa attributes with / characters in them is a real good reason to not support that! I'll rip that out. It currently does support lists of strings and symbols. :)

@jaymzh
Copy link
Collaborator

jaymzh commented Apr 13, 2016

Yeah, sorry, it's very early, I only read the description, and hadn't gotten to the code. Which I've now read. Minus the / bit, I'm good. Looks great. 👍 from me once that's changed.

@mcquin
Copy link
Contributor Author

mcquin commented Apr 13, 2016

Updated to remove support for / @jaymzh

def safe_get_attribute(*keys)
attrs = @data
keys.each do |key|
return nil unless attrs.respond_to?(:has_key?) && attrs.has_key?(key)
Copy link
Contributor

Choose a reason for hiding this comment

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

array indexes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Arrays don't respond to has_key?.

Copy link
Contributor

Choose a reason for hiding this comment

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

copied and adapted from some other code of mine (still a bit Before Caffeine for me so I may be overlooking something):

begin
  keys.inject(@data) { |memo, key| memo[key] }
rescue NoMethodError
  nil
end

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ahh that is so nice. It breaks in the case where some intermediate key is not a hash, though. Hm...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Haha rescue NoMethodError, TypeError works

@thommay
Copy link
Contributor

thommay commented Apr 13, 2016

👍

@coderanger
Copy link
Contributor

There is an RFC declaring . is the One True Separator, if we want to support that (though an array should always be supported too for places where that character is in a key).

@mcquin
Copy link
Contributor Author

mcquin commented Apr 13, 2016

@coderanger I thought about that. But I didn't want to mix provides "foo/bar" and attribute?("foo.bar").

@coderanger
Copy link
Contributor

Sure, but the former should be fixed, not the latter :)

@mcquin
Copy link
Contributor Author

mcquin commented Apr 13, 2016

🚧

@lamont-granquist
Copy link
Contributor

I think its time to argue about RFC 18 tomorrow AM:

chef-boneyard/chef-rfc#195

@coderanger
Copy link
Contributor

To be clear, I'm still 👍 on this as written. Just if we did want to support the single-string syntax it should be with .. This seems like an advanced-mode kind of API though, so I don't think we need to put the max level of UX slickness on it.

@jaymzh
Copy link
Collaborator

jaymzh commented Apr 14, 2016

👍

@tas50
Copy link
Contributor

tas50 commented Apr 18, 2016

@chef/client-core can we get another set of eyes on this since there's been some changes since the initial 👍 s

@@ -183,6 +185,18 @@ def method_missing(name, *args)

private

def safe_get_attribute(*keys)
keys.inject(@data) do |attrs, key|
unless attrs.nil? || attrs.is_a?(Hash)
Copy link
Contributor

Choose a reason for hiding this comment

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

|| attrs.is_a?(Array)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think we want to allow Array access here. The idea is to prevent accessing values as subattribute keys. We expect the structure to be a Mash until we reach 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.

Yeah but Mashes turn into Arrays once you traverse them, and attrs[key] is fine to run on an Array.

I think if you set it up and try to do something like

safe_get_attributes("etc", "passwd", "group", "wheel", "members", 0)

It'll throw a TypeError instead of giving you back "root" (on my Mac anyway).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mashes turn into Arrays once you traverse them

Whoa, ugh. Ok.

@thommay
Copy link
Contributor

thommay commented Apr 22, 2016

👍

@thommay thommay merged commit a40ff2f into master Apr 22, 2016
@tas50 tas50 deleted the OHAI-794/attribute-from-mash branch April 22, 2016 18:27
@tas50 tas50 changed the title Safely get or check the existence of attributes Add method to safely get or check the existence of attributes May 10, 2016
@chef chef locked and limited conversation to collaborators Nov 16, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Type: Enhancement Adds new functionality.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants