thens has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I need some suggestion/advice on creating a config/rules files for an application that Iam developing. The key requirements being

We basically want to process a object hierarchy. The processing rules will be taken as input in the form of a config file. The rules can be either inluce rules/exclude rules. The rules can apply to single object or a class of objects and any rules applied to the top level should descend down the levels of the tree.

I will illustrate that with an example. Let us assume Iam creating a visa processing application. We can organize the data in hierarchy like

Hope this gives an idea. The person can be a Male or Female. The visa processing rules can be like,
  1. All people from CountryA, CountryB, CountryC, CountryD should be given a visa
  2. All females from CountryZ will get visa
  3. People from CountryB and whose state is not 'xx' should be given visa.
  4. People whose name start with 'J' should not be granted a visa.

NOTE Even though rule #1 says all people from CountryB can get a visa, the rule #3 overrides it with saying only people whose state is not 'xx' can get a visa

Is there a generic module or design concept available that I can reuse. I was thinking of something like a sequence of SQL select like statements that will express this. But Iam not sure how it can take care of the overrides by the rules that follow. If this can be achieved by a perl data file with multilevel hash, I have no issues. I guess a known syntax(Perl/SQL...) will avoid the overhead of learning a new representation scheme.

Any pointers to similar work or suggestions are welcome.

-T
  • Comment on Suggestions for design of a config/rules file

Replies are listed 'Best First'.
Re: Suggestions for design of a config/rules file
by dimar (Curate) on Jun 09, 2004 at 19:24 UTC

    Use YAML. Here are just some highlights. Use YAML. It obviates the need to reinvent the wheel. Use YAML. It's easy.

    NOTES ON DATASTRUCTURE The easiest way to visualize and understand the data structure: it is just like an Excel 'spreadhsheet workbook'. Each 'worksheet' represents an element of your model. Each worksheet holds one and only one 'table'.
    You can create any level of heirarchy with this model simply by adding 'links'. You can easily translate this model in and out of a database because everything is organized as tables. You can easily translate this model into a directed graph. You can easily translate this model into just about *anything* you can represent digitally.

    NOTES ON FIELDS

    • name : the 'database-friendly' version of the name
    • caption : the 'user-input-form-friendly' version of the name

    ADDITIONAL CONSIDERATIONS

    • you can easily create links and multiple nested levels with YAML without modifying the simple datastructure

    The Code

    ### INIT script use strict; use warnings; use YAML; use Data::Dumper; my $dataroot = YAML::Load(join "", (<DATA>)); print $dataroot->{person}[0]{fname}; print "\n------------------\n"; print $dataroot->{person}[0]{lname}; print "\n------------------\n"; print $dataroot->{person}[0]{city}{caption}; print "\n------------------\n"; print Data::Dumper->Dump([$dataroot], [qw(dataroot)]); print "\n------------------\n"; 1; __END__ country: - &IDxCountryA name: CountryA caption: Country Alpha - &IDxCountryB name: CountryB caption: La Cuidad Del B - &IDxCountryC name: CountryC caption: United C Emirates state: - &IDxStateWashatovia name: washatovia caption: Washatovia country: *IDxCountryC - name: nervada_dc caption: Nervada D.C. country: *IDxCountryC city: - &IDxCityParisis name: Parisis caption: Parisis person: - fname: Samir lname: Krishnamurty city: *IDxCityParisis state: *IDxStateWashatovia country: *IDxCountryC
Re: Suggestions for design of a config/rules file
by halley (Prior) on Jun 09, 2004 at 17:42 UTC
    You're going to get a lot of comments suggesting a couple of different possibilities, and modules to match: XML and Dumper/eval.

    There are many modules to play with XML, so I won't recommend any particular one. But I don't recommend parsing XML with your own regexes. Use the code that's already been debugged.

    If security's not an issue and the data is not that big, like ~/.foobarrc files, I would go with Data::Dumper and eval. It's quick, it's easy, it's extensible without effort.

    --
    [ e d @ h a l l e y . c c ]

        By eval, I mean any of the class of Perl routines which ultimately do an eval anyway. Both require FILE and do FILE ultimately do an evaluation of the file contents. The rest is syntactic sugar.

        --
        [ e d @ h a l l e y . c c ]

Re: Suggestions for design of a config/rules file
by davidj (Priest) on Jun 09, 2004 at 18:10 UTC
    If my understanding is correct and you want to store rules, etc. in a config file, take a look at the Config::General module. It might be a useful solution.

    --davidj

      I do understand the usability of the modules like Config::General etc. My question was more related to the format/contents of the file and if there is any reference for desinging such a format, somthing like creating your custom language.

      -T
Re: Suggestions for design of a config/rules file
by jZed (Prior) on Jun 09, 2004 at 18:17 UTC
    I was thinking of something like a sequence of SQL select like statements that will express this. But Iam not sure how it can take care of the overrides by the rules that follow.
    If you do this with DBD::AnyData temporary-in-memory tables, or with any DBD that supports views and/or temporary tables, you can create a temporary table and apply the rules successively to that table. If all rules are written in the form "DELETE from temp_table WHERE ..." then you can successively apply the rules e.g. #1 would remove anyone not in CountryA-D and rule #3 would remove people from that list who lived in CountryC and state xx.

    If you want to go the non-SQL route, I think YAML is likely to be your best bet.

Re: Suggestions for design of a config/rules file
by stvn (Monsignor) on Jun 09, 2004 at 21:21 UTC
    Is there a generic module or design concept available that I can reuse.

    I wrote Tree::Parser for reasons very similar to yours. I needed to allow people to model tree-ish structures within Excel and then export them as tab-delimited files which I could parse and use. Tree::Parser is pretty flexible in terms of allowing you to build heirarchies of tree objects (the trees are Tree::Simple objects, a module I also wrote) from a variety of input styles, not just tab-delimited and even allows you to write your own custom input processors if need be. The Tree::Simple objects it produces can hold arbitrary data in their nodes as well, so there is little restriction as to the make-up of the resulting tree. Tree::Parser also supports deparsing, so its possible to easily serialize any programmatic changes back to your original files.

    Let me know if you are interested in using/trying it out, and I will be happy to answer any questions you might have.

    -stvn
Re: Suggestions for design of a config/rules file
by toma (Vicar) on Jun 10, 2004 at 07:35 UTC
    The node Persistence for options has a discussion of a similar requirement. At that time, I chose XML::Simple to store configuration information. This could have been better, since non-programmers needed to change the file, and editing XML by hand was not as simple as they would have liked.

    For my current project I am using YAML, which is working very well.

    It should work perfectly the first time! - toma