NGS is a language and a shell that I am building for systems administration tasks. Enough of the language is implemented to enable writing some useful scripts. The shell is not there yet.
Some of the Hash methods in NGS
The methods for working with Hash I have not seen all at once in other languages are:
- filterk – filter Hash by key (produces Hash)
- filterv – filter Hash by value (produces Hash)
- mapk – map Hash keys (produces Hash)
- mapv – map Hash values (produces Hash)
- mapkv – map Hash keys and values (produces Hash as opposed to map which produces an array)
- without – filters out specific key
How these are actually used? Following is an excerpt from the pollute method (function), which is a part of the AWS module. It uses several of the Hash methods I mentioned, making the method a good example. pollute
method (as in “pollute global namespace”) enables using Vpc
variable for example instead of AWS::Vpc
and so on. I would like to have this behaviour for small quick-and-dirty scripts but not as default so it’s in a method that one can optionally call.
F pollute(do_warn=true) {
vars =
_exports.filterk(/^AMI_OWNER/) +
_exports.filterv(Type).without('Res').without('ResDef') +
...
if do_warn {
warn("Polluting ...: ${vars.keys().join(', ')}")
}
vars.mapk(resolve_global_variable).each(set_global_variable)
}
Let’s go over the code above step by step:
F pollute(do_warn=true) { ... }
defines the pollute
method with optional parameter do_warn
that has default value of true
.
_exports
is a Hash containing all of the AWS’ module variables and functions, similar to NodeJS module.exports
but members are added automatically rather than explicitly. Only the methods and variables that do not start with _
(underscore) are added. One can modify _exports
in any way before the end of the module. I will write more in detail about require()
and modules in NGS in another post.
filterk(/^AMI_OWNER/)
filters all the variables that match the given RegExp
filterv(Type)
filters all the variables that are of type Type. These are AWS types’ definitions, such as Vpc, Subnet or Instance.
without('...')
filters out the types I don’t like to override.
+
between and after _exports.filterk(...)
and _exports.filterv(...)
joins the hashes.
mapk
translates variables’ names into their index (using resolve_global_variable
)
each
runs set_global_variable
with variable index and the value to set
Hash methods in other languages
I am aware that some of the methods above are present in other languages or libraries. Some examples:
- Ruby has
mapv
(transform_values) method. - Rails has
mapk
(transform_keys) andmapv.
- Perl 6 can modify values in a convenient manner:
for %answers.values -> $v is rw { $v += 10 };
.
What I have not seen is a language which has all the methods above out of the box. I have a feeling that arrays get all the fame methods while hashes (dictionaries) often get less attention in other languages.
Why NGS has all these methods?
NGS is aiming to be convenient for systems administration tasks. More often than not these tasks include data manipulation. NGS has many functions (methods) for data manipulation, including the ones listed in this post.
Update: reddit discussion
Have a nice day!