Skip to content

(MODULES-3568) Move dig to dig44 and deprecate dig #618

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

Merged
merged 1 commit into from
Jul 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ Returns the difference between two arrays. The returned array is a copy of the o

#### `dig`

DEPRECATED: This function has been replaced in Puppet 4.5.0, use dig44() for backwards compatibility or use the new version.

*Type*: rvalue.

Retrieves a value within multiple layers of hashes and arrays via an array of keys containing a path. The function goes through the structure by each path component and tries to return the value at the end of the path.
Expand Down Expand Up @@ -324,6 +326,42 @@ $value = dig($data, ['a', 'b', 'c', 'd'], 'not_found')
# $value = 'not_found'
~~~

1. **$data** The data structure we are working with.
2. **['a', 'b', 2]** The path array.
3. **'not_found'** The default value. It will be returned if nothing is found.
(optional, defaults to *undef*)

#### `dig44`
Copy link
Contributor

Choose a reason for hiding this comment

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

Please keep the entry for the old dig() around and replace its description with the deprecation warning to reduce possible confusion.

Copy link
Author

Choose a reason for hiding this comment

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

Okay, added that back in.


*Type*: rvalue.

Retrieves a value within multiple layers of hashes and arrays via an array of keys containing a path. The function goes through the structure by each path component and tries to return the value at the end of the path.

In addition to the required path argument, the function accepts the default argument. It is returned if the path is not correct, if no value was found, or if any other error has occurred.

~~~ruby
$data = {
'a' => {
'b' => [
'b1',
'b2',
'b3',
]
}
}

$value = dig44($data, ['a', 'b', 2])
# $value = 'b3'

# with all possible options
$value = dig44($data, ['a', 'b', 2], 'not_found')
# $value = 'b3'

# using the default value
$value = dig44($data, ['a', 'b', 'c', 'd'], 'not_found')
# $value = 'not_found'
~~~

1. **$data** The data structure we are working with.
2. **['a', 'b', 2]** The path array.
3. **'not_found'** The default value. It will be returned if nothing is found.
Expand Down
50 changes: 6 additions & 44 deletions lib/puppet/parser/functions/dig.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,13 @@

module Puppet::Parser::Functions
newfunction(:dig, :type => :rvalue, :doc => <<-EOS
Looks up into a complex structure of arrays and hashes and returns nil
or the default value if nothing was found.

Path is an array of keys to be looked up in data argument. The function
will go down the structure and try to extract the required value.

$data = {
'a' => {
'b' => [
'b1',
'b2',
'b3' ]}}

$value = dig($data, ['a', 'b', '2'], 'not_found')
=> $value = 'b3'

a -> first hash key
b -> second hash key
2 -> array index starting with 0

not_found -> (optional) will be returned if there is no value or the path
did not match. Defaults to nil.

In addition to the required "path" argument, "dig" accepts default
argument. It will be returned if no value was found or a path component is
missing. And the fourth argument can set a variable path separator.
DEPRECATED: This function has been replaced in Puppet 4.5.0, please use dig44() for backwards compatibility or use the new version.
EOS
) do |arguments|
# Two arguments are required
raise(Puppet::ParseError, "dig(): Wrong number of arguments " +
"given (#{arguments.size} for at least 2)") if arguments.size < 2

data, path, default = *arguments

if !(data.is_a?(Hash) || data.is_a?(Array))
raise(Puppet::ParseError, "dig(): first argument must be a hash or an array, " <<
"given #{data.class.name}")
) do |arguments|
warning("dig() DEPRECATED: This function has been replaced in Puppet 4.5.0, please use dig44() for backwards compatibility or use the new version.")
if ! Puppet::Parser::Functions.autoloader.loaded?(:dig44)
Puppet::Parser::Functions.autoloader.load(:dig44)
end

unless path.is_a? Array
raise(Puppet::ParseError, "dig(): second argument must be an array, " <<
"given #{path.class.name}")
end

value = path.reduce(data) { |h, k| (h.is_a?(Hash) || h.is_a?(Array)) ? h[k] : break }
value.nil? ? default : value
function_dig44(arguments)
end
end
56 changes: 56 additions & 0 deletions lib/puppet/parser/functions/dig44.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#
# dig44.rb
#

module Puppet::Parser::Functions
newfunction(:dig44, :type => :rvalue, :doc => <<-EOS
DEPRECATED: This function has been replaced in puppet 4.5.0.

Looks up into a complex structure of arrays and hashes and returns nil
or the default value if nothing was found.

Path is an array of keys to be looked up in data argument. The function
will go down the structure and try to extract the required value.

$data = {
'a' => {
'b' => [
'b1',
'b2',
'b3' ]}}

$value = dig44($data, ['a', 'b', '2'], 'not_found')
=> $value = 'b3'

a -> first hash key
b -> second hash key
2 -> array index starting with 0

not_found -> (optional) will be returned if there is no value or the path
did not match. Defaults to nil.

In addition to the required "path" argument, "dig44" accepts default
argument. It will be returned if no value was found or a path component is
missing. And the fourth argument can set a variable path separator.
EOS
) do |arguments|
# Two arguments are required
raise(Puppet::ParseError, "dig44(): Wrong number of arguments " +
"given (#{arguments.size} for at least 2)") if arguments.size < 2

data, path, default = *arguments

if !(data.is_a?(Hash) || data.is_a?(Array))
raise(Puppet::ParseError, "dig44(): first argument must be a hash or an array, " <<
"given #{data.class.name}")
end

unless path.is_a? Array
raise(Puppet::ParseError, "dig44(): second argument must be an array, " <<
"given #{path.class.name}")
end

value = path.reduce(data) { |h, k| (h.is_a?(Hash) || h.is_a?(Array)) ? h[k] : break }
value.nil? ? default : value
end
end
44 changes: 44 additions & 0 deletions spec/functions/dig44_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require 'spec_helper'

describe 'dig44' do
it "should exist" do
expect(Puppet::Parser::Functions.function("dig44")).to eq("function_dig44")
end

it "should raise a ParseError if there are less than 2 arguments" do
expect { scope.function_dig44([]) }.to raise_error(Puppet::ParseError)
end

it "should raise a ParseError if the first argument isn't a hash or array" do
expect { scope.function_dig44(['bad', []]) }.to raise_error(Puppet::ParseError)
end

it "should raise a ParseError if the second argument isn't an array" do
expect { scope.function_dig44([{}, 'bad']) }.to raise_error(Puppet::ParseError)
end

it "should return an empty hash when given empty parameters" do
result = scope.function_dig44([{}, []])
expect(result).to(eq({}))
end

it "should return value when given simple hash" do
result = scope.function_dig44([{"a" => "b"}, ["a"]])
expect(result).to(eq("b"))
end

it "should find hash values two levels deep" do
result = scope.function_dig44([{"a" => {"b" => "c"}}, ["a", "b"]])
expect(result).to(eq("c"))
end

it "should return default value if nothing was found" do
result = scope.function_dig44([{}, ["a", "b"], "d"])
expect(result).to(eq("d"))
end

it "should work on booleans as well as strings" do
result = scope.function_dig44([{"a" => false}, ["a"]])
expect(result).to(eq(false))
end
end
16 changes: 8 additions & 8 deletions spec/functions/dig_spec.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
require 'spec_helper'

describe 'dig' do
it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) }
it { is_expected.to run.with_params('bad', []).and_raise_error(Puppet::ParseError) }
it { is_expected.to run.with_params({}, 'bad').and_raise_error(Puppet::ParseError) }

it { is_expected.to run.with_params({}, []).and_return({}) }
it { is_expected.to run.with_params({"a" => "b"}, ["a"]).and_return("b") }
it { is_expected.to run.with_params({"a" => {"b" => "c"}}, ["a", "b"]).and_return("c") }
it { is_expected.to run.with_params({}, ["a", "b"], "d").and_return("d") }
it { is_expected.to run.with_params({"a" => false}, ["a"]).and_return(false) }
it "should exist" do
expect(Puppet::Parser::Functions.function("dig")).to eq("function_dig")
end

it "should give a deprecation warning when called" do
scope.expects(:warning).with("dig() DEPRECATED: This function has been replaced in Puppet 4.5.0, please use dig44() for backwards compatibility or use the new version.")
scope.function_dig([{}, []])
end
end