Beefy Boxes and Bandwidth Generously Provided by pair Networks Frank
P is for Practical
 
PerlMonks  

VarStructor

by Wassercrats
on Apr 14, 2004 at 22:56 UTC ( #345239=sourcecode: print w/ replies, xml ) Need Help??

Category: Utility Scripts
Author/Contact Info barry@polisource.com
Description:

This script is obsolete. See updated script at VarStructor 1.0.

An alternative to the eventually-to-be-deprecated reset function, plus lists variables and their values. Place VarStructor in the script containing the variables. Configurable with $CLEAR and $OMIT.

One advantage over some alternatives for listing variables is that variables in the code will be listed even if they weren't "seen" during run time. This includes variables within comments, though that part isn't an advantage (bottom of my list of things to fix).

Other limitations are it doesn't handle hashes or variables beginning with "_" and spacey values will be spacey looking (not visually delimited) in the output. I heard something about variable names containing a space not working too (whatever they are). I might fix all that, depending on the response I get.

Code removed by author. I no longer want to contribute to this community.

Comment on VarStructor
Re: VarStructor
by calin (Deacon) on Apr 15, 2004 at 18:51 UTC

    This is a joke, right?

      You know very well it's not a joke. I got tired of reading about the limitations and complexities of other ways of accomplishing similar things. This script is the best way to accomplish what I want to do, and the hash support is easy to implement if I or someone else wants it.

      As far as I could tell, it's safer and more flexible than reset, it's faster and gives a neater display than Xref if you just want the variables, and it doesn't require Perl compilation. It doesnt't HAVE to be used from within the target script, and you could even use it on documentation and compare the results with the script you're documenting to see if you left out any descriptions of important variables.

      What's a joke is everyone's local variable worship and fear of using eval on a string and related issues like passing values to subroutines without parameters. Following those "rules" would just slow me down and make my code longer and more complex.

      An even funnier joke is that people are assuming that a site mapper/link checker script of mine, of 3200 lines, should be rewritten, even though I say it works great and isn't difficult for me to understand. The most difficult to understand parts are those using functions that I forgot how to use, and rewriting it would be insane even if I didn't forget anything.

      With all the bugs in so much software today, you would think that people would want to learn how I was able to create such a long script without using strict, without OO, with all globals, with reinvented modules built in, and all the other "bad" things, THAT WORKS. It's a web application that runs on my home computer through a web interface (though I'm not running a web server at home) and I'm willing to put it on line temporarily for a few people who want a free site map or local link check and who's minds would be blown when it works. Please wear a helmet.

        I must admit that it gives me a chuckle that you would think that 3200 lines is really long.

        I just did a wc on a source directory for a significant application that I'm working on. Over 100,000 lines of code, comments and documentation. Without even looking at how much HTML we have. Of course this application does a little more than just check links...

        Do you think that your techniques would scale to a team of people working on a code base which is an order of magnitude larger than yours? With a lot of interacting pieces? And why do you think that I should believe that yours really works without any bugs? I know lots of developers who think that their own code works flawlessly. I've known far fewer who could prove it.

        To seriously answer your question, I'm not interested in knowing how it is possible to write a link checker in 3200 lines. I'd prefer to learn how to write one in under 100 lines. Or one with lots more features, still in a small fraction of yours.

        And, of course, I want to be able to scale up my development practices to also be useful when I work with a team of people on far larger code bases. (While still keeping the functionality per line up there.)

        With all the bugs in so much software today, you would think that people would want to learn how I was able to create such a long script without using strict, without OO, with all globals, with reinvented modules built in, and all the other "bad" things, THAT WORKS.

        I don't get this at all. You know how it reads to me? Something like this:

        I was able to build a house without a saw, hammer or nails, but with just rocks and sticks and mud.

        Sure you can build a great house like that if you pay attention to detail and use a lot of skill, but if you have tools to help you with the details and can help you build it better and faster, why not use them?

        That said, I think you should not rewrite your code. If you've already written it and it works for you, use it. If some poor soul comes after you and can't understand what you've done, let him rewrite it so he can. But gratuitous rewriting of working software is a short path to ruin.

Re: VarStructor
by Wassercrats on Apr 30, 2004 at 20:08 UTC
      Oh yeah, you're right. What a horrible update notice. It deserves a -9.
Re: VarStructor
by Anonymous Monk on Sep 15, 2004 at 05:29 UTC
    # Copyright (c) 2004 Barry Kaminsky. All rights reserved. This program + is free software; you can redistribute it and/or modify it under the + same terms as Perl itself. # Last minute changes made May 2, 2004, 4:00 AM EST without much testi +ng # VarStructor is an alternative to Perl's reset function, which is exp +ected to be deprecated. It could also be used to print variables and +their values, including "my" variables. See comments at top of sub VA +RSTRUCTOR for configuration information. ################################# # Test variables (could be deleted) %hash1=("key1"=>"value1","key2"=>"value2"); $hash2{"key1"}="value1"; $hash2{"key2"}="value2"; $Simple_Var = 'simple'; @Simple_Arr = ('simple1','simple2'); ################################# &VARSTRUCTOR('show', 'E: subs(VARSTRUCTOR)'); # Test parameters sub VARSTRUCTOR { ########################################################## # 1st parameter: # Assign "show" to print variables and values or # "clear" to clear variables. For security reasons, the # default is clear. splice (@_,0,0,'clear') if ($_[0] !~ /^\s*(show|clear)\s*$/i); $Function = $_[0]; # 2nd parameter: # Comma-separated list of variables, subroutines, and # labels, whose variables will be included or excluded. # Labels must be of labeled blocks that are wrapped in # braces. This parameter must begin with "I:" or "E:" # (include or exclude). # # You can't include or exclude array elements, hash # keys or hash values. Legal variables for this # parameter begin with $, @, and %, followed by a # string of word characters not beginning with a digit. # # The label and subroutine name lists must be enclosed # in separate sets of parentheses, following the word # "labels" or "subs". A comma after the closing # parenthesis is necessary when another item in this # parameter follows. Commas also must separate the # labels and subroutine names within the parentheses. # Within the code to be parsed, there must be nothing # preceding the labels and the "sub"s on the # same line except for optional spaces, and the # subroutines and labeled blocks must end with the # next "}" that is at the same level of indentation as # the first character of the label or the "s" of "sub". # Within the parameters, the "&" is optional before # subroutine names and the ":" is optional after labels. splice (@_,1,0,'') if ($_[1] !~ /^\s*(i:|e:)/i); $Variables = "$_[1]"; # 3rd parameter: # Target file. Default is $0, indicating the file # VarStructor is being run from. $_[2] = "$0" if $_[2] =~ /^\s*$/; $Targ = "$_[2]"; ########################################################## open(IN, $Targ) or die 'Can not open file'; @file = <IN>; close IN; $FILE = join ('',@file); $FILE =~ s/[;\n]\s*#[^\n]*//sg; # Delete comments ### Prevent parsing of some quoted strings by deleting here docs. R +arely, a single quoted string would be mistaken for a variable if not + in a here doc. # Delete here docs with quoted identifiers $FILE =~ s/<<\s*('|"|`) ([^\n]*?([^\\]|[^\\]\\\\))\1 # Match here doc identifier, which end +s with an unescaped closing quote. Limitation: an even number of slas +hes greater than two at the end of the identifier would be wrongly in +terpreted as escaping the quote and the here doc value would probably + not get deleted. .*?\n\2\n//sgx; # Delete here docs with unquoted identifiers $FILE =~ s/<<(\w+);.*\n\1\n//sg; # Isolate subroutines to search, according to $Variables while ($Variables =~ s/(?<=subs\()\s*\&?(\w+)\s*(,+|\))//) { $FILE =~ s/(^|\n)(\s*)sub\s*\Q$1\E\s*\{.*?\n\2\}//s; $ISOLATED_SUBS .= "$&"; } # Isolate labeled blocks to search, according to $Variables while ($Variables =~ s/(?<=labels\()\s*(\w+):?\s*(,+|\))//) { $FILE =~ s/(^|\n)(\s*)\Q$1\E:.*?\{.*?\n\2\}//s; $ISOLATED_LABELS .= "$&"; } # Delete or include individual variables, according to $Variables while ($Variables =~ s/[\$|\@|\%][^\d\W]\w*//) { $ONE_VAR = "$&"; $VARS_ONLY .= "$ONE_VAR='';" if $Variables =~ /^\s*I:/i; $FILE =~ s/\Q$ONE_VAR\E//g if $Variables =~ /^\s*E:/i; } $FILE = "$VARS_ONLY $ISOLATED_SUBS $ISOLATED_LABELS" if $Variables +=~ /^\s*I:/; $FILE =~ s/\Q($ISOLATED_SUBS|$ISOLATED_LABELS)\E// if $Variables =~ + /^\s*E:/; # Find arrays. If not an array used in push, require an equals sign + to avoid quoted email addresses that look like arrays. while (($FILE =~ s/([^\\]|[^\\]\\\\)(\@[^\d\W]\w*)\s*=//)|| # Find scalars/array elements after ++ or -- ($FILE =~ s/(?:[^\\]|[^\\]\\\\)(\+\+|--)\s*(\$[^\d\W]\w*(\[.*?\])?) +//)|| # Find scalars/array elements before assignment operators, "++", "- +-", "." or ".=" ($FILE =~ s/([^\\]|[^\\]\\\\)(\$[^\d\W]\w*(\[.*?\])?)\s*(=|\+=|-=|\ +*=|\/=|\%=|\*\*=|\+\+|--|\.)//)|| # Find arrays assigned to with push. ($FILE =~ s/push[^\w_]*([^\\]|[^\\]\\\\)(\@[^\d\W]\w*)//)) { $ONE_VAR = $2; $ONE_VAR =~ s/^\$(.*)\[.*/\@$1/; # Convert element to its array ($EVAL_VAR = $ONE_VAR =~ /^\$/ ? "$ONE_VAR='';" : "$ONE_VAR=();" +) if $Function =~ /^clear$/i; # To do: print index numbers next to values ($EVAL_VAR = "\\$ONE_VAR = $ONE_VAR\\n") if $Function =~ /^show$ +/i; push (@ALL_VAR, "$EVAL_VAR"); } # Extract hashes while (($FILE =~ s/([^\\]|[^\\]\\\\)\%([^\d\W]\w*)\s*=//)|| ($FILE =~ s/([^\\]|[^\\]\\\\)\$([^\d\W]\w*)\{[^\n]*\}\s*=//)) { $ONE_HASH = "$2"; push @HASH_DISPLAY, "print \"\\n\%$ONE_HASH\\n\";" . "foreach \$key (sort(keys \%$ONE_HASH))" . "{print \$key, '=', \$$ONE_HASH\{\$key\}, \"\\n\";}" if $Function =~ /^show$/; push @HASH_DISPLAY, "\%$ONE_HASH=();" if $Function =~ /^clear$/; } @ALL_VAR = grep {++$count{$_} < 2} @ALL_VAR; @ALL_VAR = sort @ALL_VAR; $ALL_VAR = join ('',@ALL_VAR); $ALL_VAR =~ s/.*/print"$&";/ if $Function =~ /^show$/i; eval $ALL_VAR; @HASH_DISPLAY = grep {++$count{$_} < 2} @HASH_DISPLAY; @HASH_DISPLAY = sort @HASH_DISPLAY; $HASH_DISPLAY = join ('',@HASH_DISPLAY); eval $HASH_DISPLAY; }
      Looks like it was useful enough for someone to save. Weren't you afraid my bad code would make your computer explode?

      Unfortunately, you posted VarStructor 1.0 in the VarStructor thread.

Back to Code Catacombs

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://345239]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (6)
As of 2014-04-18 05:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (461 votes), past polls