thillaiselvan
thillaiselvan

Reputation: 637

Perl program for extracting the functions alone in a Ruby file

I am having the following Ruby program.

    puts "hai"
     def mult(a,b)
        a * b
     end
     puts "hello"
     def getCostAndMpg
       cost = 30000  # some fancy db calls go here
       mpg = 30
       return cost,mpg
     end
   AltimaCost, AltimaMpg = getCostAndMpg
   puts "AltimaCost = #{AltimaCost}, AltimaMpg = {AltimaMpg}"

I have written a perl script which will extract the functions alone in a Ruby file as follows

while (<DATA>){ 
   print if ( /def/ .. /end/ );
}

Here the <DATA> is reading from the ruby file.

So perl prograam produces the following output.

def mult(a,b)
    a * b
end
def getCostAndMpg
    cost = 30000  # some fancy db calls go here
    mpg = 30
    return cost,mpg
end

But, if the function is having block of statements, say for example it is having an if condition testing block means then it is not working. It is taking only up to the "end" of "if" block. And it is not taking up to the "end" of the function. So kindly provide solutions for me.

Example:

def function
   if x > 2
      puts "x is greater than 2"
   elsif x <= 2 and x!=0
      puts "x is 1"
  else
      puts "I can't guess the number"
  end  #----- My code parsing only up to this
end

Thanks in Advance!

Upvotes: 0

Views: 111

Answers (3)

bvr
bvr

Reputation: 9697

Another option could be counting level of program, something like this:

my $level = 0;
while(<DATA>) {
    if(/\b def \b/x .. /\b end \b/x && $level == 0) {
        $level++ if /\b if  \b/x;   # put all statements that closes by end here
        $level-- if /\b end \b/x;
        print;
    }
}

I am not all that familiar with ruby syntax, so you need to put all statements that are closed by end into regex with $level++.

Please note I added \b around those keywords to make sure you are matching whole word and not things like undef as start of function.

Upvotes: 0

thatbrentguy
thatbrentguy

Reputation: 44

If your code is properly indented, you just want lines that start with def or end, so change your program to:

while (<DATA>){
   print if ( /^def/ .. /^end/ );
}

Or run it without a program file at all - run the program from the command line, using -n to have perl treat it as a while loop reading from STDIN:

perl -n -e "print if ( /^def/ .. /^end/ );" < ruby-file.rb

Upvotes: 1

Nylon Smile
Nylon Smile

Reputation: 9436

I am not familiar with ruby syntax but if you can ensure good indentation all over the code, you can check based on indentation. Something similar to:

my $add = 0;
my $spaces;
while(my $str = <DATA>) {
    if (! $add && $str =~ /^(\s*)def function/) {
        $add = 1;
        $spaces = $1;
    }
    if ($add) {
        print $_;
        $add = 0 if ($str =~ /^$spaces\S/);
    }
}

Upvotes: 1

Related Questions