Changes between Initial Version and Version 1 of ScriptableInterface


Ignore:
Timestamp:
Mar 7, 2012, 1:32:22 AM (13 years ago)
Author:
manualwiki
Comment:

created ri page, and filled it with content

Legend:

Unmodified
Added
Removed
Modified
  • ScriptableInterface

    v1 v1  
     1 
     2== Scriptable !RefactorErl interface == 
     3 
     4ris is similar to ri, with the following basic ideas: \\ 
     5 * results are always returned via the function return value. \\ 
     6 * no mandatory standard output. \\ 
     7 * arguments very regular - semantic queries for almost everything. \\ 
     8 * you can also input a semantic query via atoms instead of strings to ease escaping.\\ 
     9 * operations are composable (i.e., continue one where another has left off) - queries and refactorings can go back and forth. \\ 
     10 * you can perform a series of batch refactorings in a single step by selecting multiple entities at once. \\ 
     11 
     12== Usage examples == 
     13 
     14'''Adding files''' 
     15 
     16{{{ 
     17Added = ris:add_byname("mymods.erl"). 
     18ReAdded = ris:add('mods[name~"mymodu.*"]'). 
     19}}} 
     20 
     21'''Dropping files''' 
     22 
     23{{{ 
     24ris:drop('mods[name ~ "mymo.*"]'). 
     25}}} 
     26 
     27'''Refactorings''' 
     28 
     29{{{ 
     30RenamedVars = ris:rename("mods.fun.var[name=="Colour"]", "Color"). 
     31 
     32MovedFuns = ris:move("mods[name ~ "^referl_.*"].fun[exported==false]", 
     33                     fun(F)-> 
     34                         ris:qstr([F,".mod.name"])++"_util" 
     35                     end). 
     36 
     37Moved = ris:move("mods[name==mod1].fun[name==fun1 and arity==3]", mod2). 
     38 
     39NewFun = ris:extract("mods[name==module1] 
     40                         .fun[name==f and arity==0] 
     41                             .expr[last==false]", 
     42                      mynewfun). 
     43 
     44NewVar = ris:intvar("mods[name==module1] 
     45                        .fun[name==f and arity==0] 
     46                            .expr[index==1].esub[class/=pattern]", 
     47                    "Varname"). 
     48 
     49NewRec = ris:intrec("mods[name==module1] 
     50                        .fun[name==f and arity==0] 
     51                            .expr[index==1].esub[class/=pattern]", 
     52                     {newrec,[field1,field2]}). 
     53 
     54NewFun = ris:reorder("mod[name==mod1].fun[name==fun1,arity==3]", 
     55                     [3,2,1]). 
     56 
     57NewFun = ris:tupfun("mod[name==mod1].fun[name==fun1,arity==3]", 
     58                    {1,2}). 
     59 
     60ris:generalize("mod[name==china].fun[name==sum].var[name=="A"]"). 
     61 
     62ris:eliminate("mod[name==china].fun[name==sum].var[name=="A"]"). 
     63 
     64ris:inline("mod[name==china].fun[name==sum] 
     65               .expr[type/=pattern and index==1]"). 
     66}}} 
     67 
     68 
     69== Operators == 
     70 
     71The result of the queries can be combined with the following set operators: \\ 
     72* '''Intersection''': The following example takes the intersection of the files included by the two modules. 
     73 
     74{{{ 
     75ris:q({"mods[name==mod1].includes", intersect, 
     76       "mods[name==mod2].includes"}). 
     77}}} 
     78 
     79* '''Union''': similar to the above (use key 'union'). \\ 
     80* '''Substraction''': similar to the above (use key 'minus'). \\ 
     81* '''Range''': Ranges of expressions can be selected which denotes a list of continuous expressions between two syntactical siblings. An empty semantic query denotes the beginning or end of a block when used as the initial or final limit respectively. In this example, the expression range starts from the (first) match expression that contains "Var1" in the pattern side up to the end of the syntactical block. 
     82 
     83{{{ 
     84NewFun = ris:extract({"mods[name=mod1] 
     85                          .fun[name==f and arity==0] 
     86                             .expr[type==match_expr] 
     87                                 .esub[class==pattern and 
     88                                       type==variable and 
     89                                       .var[name=="Var1"]]", 
     90                       range, ""}, mynewfun). 
     91}}} 
     92 
     93* '''Sequence''': Queries can be sequenced to continue a query from where another has left off. This example first adds the module from file 'mymodule.erl'. The add call returns the entities loaded. A semantic query aggregate of a list works by executing the first query (or in this case, specifying a starting entity), and then running the next query in the chain (in this case getting the name of files included by the add call). 
     94 
     95{{{ 
     96ris:q([ris:add_byname("mymodule.erl"),".includes.name"]). 
     97}}} 
     98 
     99* '''Another sequence example''': The following example shows an example for composition. It first renames all functions whose name is 'duck' to 'quack'. It then appends the suffix '_quacker' to the name of all functions which call these quacks. The new name is automatically converted to an atom. 
     100 
     101 
     102{{{ 
     103New = ris:rename('mods.fun[name==duck]',quack), 
     104Callers = ris:q([New,".callers"]), 
     105[ris:rename(Fun,atom_to_list(Name)++"_quacker") || 
     106 Fun <- Callers, 
     107 Name <- ris:q([Fun,".name"])]. 
     108 New = ris:rename('mods.fun[name==duck]',quack), 
     109 Callers = ris:q([New,".callers"]), 
     110 ris:rename(Callers, 
     111            fun(Fun)-> 
     112                ris:qstr([Fun,".name"]) ++ "_quacker" 
     113            end). 
     114}}} 
     115 
     116== Textual display == 
     117 
     118Use '''ris:show/1''' to stringify entities. '''ris:show/2''' 
     119does the same while accepting additional options already known for '''ri:q/3'''. Use 
     120the respective '''ris:print/1''' and '''ris:print/2''' functions for screen and file output. 
     121 
     122{{{ 
     123ris:print(ris:q("mods.fun")). 
     124}}} 
     125 
     126The following gives the same result set, but written to the given file and annotated 
     127with line numbers. (Note that you could also manually write the output 
     128of '''ris:show/1''' to a file.) 
     129 
     130{{{ 
     131ris:print(ris:q("mods.fun"), 
     132          [{out,"funs.txt"}, linenum]). 
     133}}}