{"action":"created","issue":{"url":"https://api.github.com/repos/chef/chef-rfc/issues/77","labels_url":"https://api.github.com/repos/chef/chef-rfc/issues/77/labels{/name}","comments_url":"https://api.github.com/repos/chef/chef-rfc/issues/77/comments","events_url":"https://api.github.com/repos/chef/chef-rfc/issues/77/events","html_url":"https://github.com/chef/chef-rfc/pull/77","id":52032996,"number":77,"title":"Attribute API 2","user":{"login":"danielsdeleo","id":37162,"avatar_url":"https://avatars.githubusercontent.com/u/37162?v=3","gravatar_id":"","url":"https://api.github.com/users/danielsdeleo","html_url":"https://github.com/danielsdeleo","followers_url":"https://api.github.com/users/danielsdeleo/followers","following_url":"https://api.github.com/users/danielsdeleo/following{/other_user}","gists_url":"https://api.github.com/users/danielsdeleo/gists{/gist_id}","starred_url":"https://api.github.com/users/danielsdeleo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danielsdeleo/subscriptions","organizations_url":"https://api.github.com/users/danielsdeleo/orgs","repos_url":"https://api.github.com/users/danielsdeleo/repos","events_url":"https://api.github.com/users/danielsdeleo/events{/privacy}","received_events_url":"https://api.github.com/users/danielsdeleo/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":19,"created_at":"2014-12-15T20:15:13Z","updated_at":"2015-03-09T15:52:13Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/chef/chef-rfc/pulls/77","html_url":"https://github.com/chef/chef-rfc/pull/77","diff_url":"https://github.com/chef/chef-rfc/pull/77.diff","patch_url":"https://github.com/chef/chef-rfc/pull/77.patch"},"body":"**NOTE:** This RFC is incomplete, the specification of the new feature is TBD.\r\n\r\nThis RFC describes a new attributes API to be added alongside the current one. The goals of this new API are:\r\n\r\n* Separate desired and observed state.\r\n* Structure the syntax in a way that \"trainwreck\" errors\r\n  (`NoMethodError` for `[]` on `nil`) can be avoided.\r\n* Structure the syntax in a way that attribute tracing can be\r\n  implemented simply.\r\n* Separate node-specific persistent storage from\r\n  cookbook/role/environment attributes.\r\n* Structure the syntax in a way that can be implemented efficiently.\r\n\r\nThis RFC is adapted from https://github.com/opscode/chef-rfc/pull/9 which is retracted."},"comment":{"url":"https://api.github.com/repos/chef/chef-rfc/issues/comments/77880411","html_url":"https://github.com/chef/chef-rfc/pull/77#issuecomment-77880411","issue_url":"https://api.github.com/repos/chef/chef-rfc/issues/77","id":77880411,"user":{"login":"danielsdeleo","id":37162,"avatar_url":"https://avatars.githubusercontent.com/u/37162?v=3","gravatar_id":"","url":"https://api.github.com/users/danielsdeleo","html_url":"https://github.com/danielsdeleo","followers_url":"https://api.github.com/users/danielsdeleo/followers","following_url":"https://api.github.com/users/danielsdeleo/following{/other_user}","gists_url":"https://api.github.com/users/danielsdeleo/gists{/gist_id}","starred_url":"https://api.github.com/users/danielsdeleo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/danielsdeleo/subscriptions","organizations_url":"https://api.github.com/users/danielsdeleo/orgs","repos_url":"https://api.github.com/users/danielsdeleo/repos","events_url":"https://api.github.com/users/danielsdeleo/events{/privacy}","received_events_url":"https://api.github.com/users/danielsdeleo/received_events","type":"User","site_admin":false},"created_at":"2015-03-09T15:52:13Z","updated_at":"2015-03-09T15:52:13Z","body":"In the method chaining syntax it should be pretty straightforward to make array append do what you mean; e.g., in the given example `default_attr('foo', 'bar').append('thing')` the DSL owns the object that's getting `#append` called on it, so it can infer you want an Array. We could alias that as `#<<`, as well. One question though, is how these should handle conflicts; if I already have a non-array value, does an append operation nuke it, or raise an error? I'm partial to the latter as I think 99% of the time it would be a user mistake, but could be persuaded otherwise.\r\n\r\nAs for the array of hashes thing, I'll have to think about that. I will note that every example of it that I've seen can be implemented as a map; in this example, for instance:\r\n\r\n```ruby\r\n[\r\n  {\r\n    'name' => 'bigbla',\r\n    'val' => 'doof',\r\n  },\r\n  {\r\n    'name' => 'smallbla',\r\n    'val' => 'book',\r\n  }\r\n]\r\n```\r\n\r\nThe \"name\" attribute is probably unique so you could do this instead:\r\n\r\n```ruby\r\n{\r\n  'bigbla' => {\r\n    'name' => 'bigbla',\r\n    'val' => 'doof',\r\n  },\r\n  'smallbla' => {\r\n    'name' => 'smallbla',\r\n    'val' => 'book',\r\n  }\r\n}\r\n```\r\n"}}