perl

Java : chop and chomp

Perl have very handy Functions to clean up trailing garbage in Strings …

  • chop : deletes the last character of a string. Useful when you append delimiter in a loop, so that the last addition has to be cleaned up
  • chomp : removes trailing sequence of the same character. if the character/s at the end do not match the specs nothing is deleted. Useful to cleanup new-lines/s at the end. Normally happens when reading from file.

Here are those useful Functions implemented for Java :

public class Main {
  
  public static <ARG> void say(ARG arg) { System.out.println(arg); }

  //removing trailing characters
  public static String chomp(String str, Character repl) {
    int ix = str.length();
    for (int i=ix-1; i >= 0; i-- ){
      if (str.charAt(i) != repl) break;
      ix = i;
    }
    return str.substring(0,ix);
  }
  
  //default case, removing trailing newlines
  public static String chomp(String str) {
    return chomp(str,'\n');
  }  

  //hardcut  
  public static String chop(String str) {
    return str.substring(0,str.length()-1);
  }
  
  public static void main(String[] args) {
    say(chomp("hi...",'.'));
    say(chomp("hello\n\n",'\n'));
    say(chomp("hello\n\n"));
    say(chop("howdy."));
    say(chomp("hi...++",'.'));      
  }
}

------

hi
hello
hello
howdy
hi...++

Perl: __DATA__ section

This is my first Perl post. I wanted to explore a less known feature of Perl which is very useful at times.

Lets say as in my case that you need to combine and then compress .js and .css files from all over the place.
What I mean is that instead of importing in your html multiple different files you want to just import one compressed javascript file and one compressed css file.

Your first instinct may be, is to create a hash and describe all files locations … but may be the simple and dirty approach is better, enter the Perl __DATA__ section.

It is very clever idea, what if you can treat part of the source code file as a different file i.e. file within a file. Simply said everything after the __DATA__ token could be accessed via the <DATA> file handle.

Saying : @array = <DATA> will slurp everything into the @array, one line per element. In the example below i’m also removing the new line symbol.

So how do we setup which files to compress ? Simple, first type __DATA__ at the end of the file and then just use any command to append the path/file spec. I used those :

  • ls -w1 -d $PWD/blah/*.js >> compress.pl
  • ls -w1 -d $PWD/blah/*.css >> compress.pl

… several times. Don’t forget use append >>, not overwrite >

What does the script do :

  • read the __DATA__ section into the @files array
  • filter .js and .css and create a space separated string
  • using the strings from above build commands to concatenate the two groups
  • run the tools to compress concatenated files
#!/usr/bin/env perl
use strict;

sub run {
	my $cmd = shift @_;
	print "> $cmd\n";
	qx/$cmd/
}

#concatenated files
my $cat_js = 'cat.js';
my $cat_css = 'cat.css';
my $out = 'out';
#define compress commands
my $js_cmd = "/usr/local/bin/uglifyjs -c -m -- $cat_js > $out.js";
my $css_cmd = "yui-compressor --type css $cat_css > $out.css";

#read the DATA section
my @files = map {s/\n//;$_} <DATA>;
#extract js and css file
my $js_files  = join ' ', (grep /js$/, @files);
my $css_files = join ' ', (grep /css$/, @files);

#concatenate files
my $js_cat  = "cat $js_files > $cat_js";
my $css_cat = "cat $css_files > $cat_css";

run($js_cat);
run($js_cmd);

run($css_cat);
run($css_cmd);

#ls -w1 -d $PWD/*.*  >> compress.pl

__DATA__

One more thing, what is the purpose of the first line …

Shebang

If you make the file executable and have :

#!/usr/bin/perl

or

#!/usr/bin/env perl

as a first line then instead of calling the script like this :

perl compress.pl

you can do it this way :

./compress.pl