Higml: Hierarchical, Cascading, Dynamic Configuration
Purpose
Higml allows you to write hierarchical, cascading, dynamic configuration files with Ruby. It visually reflects the conditions governing how rules are applied, allowing otherwise-complicated rules to be expressed concisely and understood easily.
Examples
Applying Hierarchical, Cascading Rules
# Higml rules; let's pretend they're in rules.higml action:create :channel Create Saved Searchaction:show :channel Searchsearch_type:job :channel Job Search# Let's pretend the following is run by ruby rules = "rules.higml"input1 = {:action => "show"} input2 = {:action => "show", :search_type => "job"} input3 = {:action => "create", :search_type => "job"}Higml.values_for(input1, rules) ~> {:channel => "Search"}Higml.values_for(input2, rules) ~> {:channel => "Job Search"}Higml.values_for(input3, rules) ~> {:channel => "Create Saved Search"}
Higml checks an input hash for key/value pairs and builds an output hash. Higml rules are cascading in that if a matching rule is defined later in the Higml file, it takes precedence over a previously defined rule.
You can see this with inputs 1 & 2. input2 matches the action:show rule, but it also matches the search_type:job rule which is defined later. The search_type:job rule therefore takes precedence.
Higml is hierarchical in that it does not apply child (indented) rules if the parents don’t match. You can see this by comparing inputs 2 & 3;
Dynamic Output
# Higml rules; let's pretend they're in rules.higml action:show :keywords= @keywords# Let's pretend everything that follows is run by ruby # Context object context = Object.new context.instance_variable_set(:@keywords, "cat mouse bird")# Higml invocation, including context object Higml.values_for({:action => "show"}, 'rules.higml', context) ~> {:keywords => "cat mouse bird"}
Whenever Higml encounters = in the output definition, it uses instance_eval on the context object on the text that follows; in this case, @keywords.
Rule Application Summarized
- Rules take the form
input_key:valueorinput_key. If value is not present, any value (including nil) will cause the rule to be applied. - Multiple rules can be present on the same line, separated by commas. Example:
action:show, action:new. This is equivalent to anOR– if any rule matches, the rule is applied. - Indented (child) rules are only checked if their parent matches.
- Output definitions take the form
:output_key Valueor:output_key= code_instance_evald_in_context. - Output definitions written later on the page take precedence over those written earlier,
Pronunciation
It’s pronounced like “hig-uh-mole”.