On Nov 13, 2008, at 13:29 , Spencer Rinehart wrote:

>
> On Fri, 2008-11-14 at 06:03 +0900, Pit Capitain wrote:
>> Really impressive, Ryan! Do you know of similar tools for Java?
>
> There is Simian - http://www.redhillconsulting.com.au/products/ 
> simian/ -
> it actually works a bit better than flay at the moment - although flay
> has promise for working better with ruby code.

Umm... Actually... flay kicks simian's ass. :P

Simian, as well as a similar java tool I've used called same, have  
completely different objectives than flay. AFAIK, they're only  
normalizing whitespace and stripping comments and looking for  
duplicate code. I'm sure of that for same as I studied it for porting.  
But, I'm not positive about simian.

Simian would NEVER point this out:

> Matches found in :defn (mass = 32)
>   A: ../../drawr/dev/lib/drawr.rb:38
>   B: ../../png/dev/lib/png.rb:181
>
> A: def write(file)
> B: def save(path)
> A:   File.open(file, "wb") { |f| f.write(to_s) }
> B:   File.open(path, "wb") { |f| f.write(to_blob) }
>    end

especially considering the code is actually written like this:

>     def write(file); File.open(file, 'wb') { |f| f.write to_s }; end

vs

>   def save(path)
>     File.open path, 'wb' do |f|
>       f.write to_blob
>     end
>   end


Notice that there are 11 duplicates found by simian. Notice that there  
are 11 matches listed by flay as identicial... but then also notice  
that flay 10 more similarities that are also candidates for  
refactoring. That is where flay really differentiates itself from the  
rest. It is NOT just looking at text. It is looking at the structure  
of your code.

> % java -jar bin/simian-2.2.24.jar -language=ruby unit/itemconfig.rb
> Similarity Analyser 2.2.24 - http://www.redhillconsulting.com.au/products/simian/index.html
> Copyright (c) 2003-08 RedHill Consulting Pty. Ltd.  All rights  
> reserved.
> Simian is not free unless used solely for non-commercial or  
> evaluation purposes.
> {failOnDuplication=true, ignoreCharacterCase=true,  
> ignoreCurlyBraces=true, ignoreIdentifierCase=true,  
> ignoreModifiers=true, ignoreStringCase=true, language=Ruby,  
> threshold=6}
> Found 6 duplicate lines in the following files:
>  Between lines 464 and 472 in unit/itemconfig.rb
>  Between lines 304 and 310 in unit/itemconfig.rb
> Found 6 duplicate lines in the following files:
>  Between lines 623 and 630 in unit/itemconfig.rb
>  Between lines 463 and 470 in unit/itemconfig.rb
> Found 7 duplicate lines in the following files:
>  Between lines 294 and 301 in unit/itemconfig.rb
>  Between lines 652 and 660 in unit/itemconfig.rb
> Found 8 duplicate lines in the following files:
>  Between lines 827 and 837 in unit/itemconfig.rb
>  Between lines 664 and 673 in unit/itemconfig.rb
> Found 8 duplicate lines in the following files:
>  Between lines 529 and 539 in unit/itemconfig.rb
>  Between lines 369 and 379 in unit/itemconfig.rb
>  Between lines 895 and 905 in unit/itemconfig.rb
> Found 10 duplicate lines in the following files:
>  Between lines 842 and 852 in unit/itemconfig.rb
>  Between lines 476 and 486 in unit/itemconfig.rb
> Found 16 duplicate lines in the following files:
>  Between lines 680 and 702 in unit/itemconfig.rb
>  Between lines 850 and 872 in unit/itemconfig.rb
> Found 18 duplicate lines in the following files:
>  Between lines 706 and 734 in unit/itemconfig.rb
>  Between lines 343 and 371 in unit/itemconfig.rb
> Found 19 duplicate lines in the following files:
>  Between lines 310 and 332 in unit/itemconfig.rb
>  Between lines 673 and 695 in unit/itemconfig.rb
> Found 58 duplicate lines in the following files:
>  Between lines 737 and 826 in unit/itemconfig.rb
>  Between lines 374 and 463 in unit/itemconfig.rb
> Found 93 duplicate lines in the following files:
>  Between lines 855 and 989 in unit/itemconfig.rb
>  Between lines 489 and 623 in unit/itemconfig.rb
> Found 490 duplicate lines in 21 blocks in 1 files
> Processed a total of 692 significant (1062 raw) lines in 1 files
> Processing time: 0.302sec

vs:

> % ruby -Ilib bin/flay unit/itemconfig.rb
> Processing unit/itemconfig.rb
>
> IDENTICAL Matches found in :block (mass*2 = 640)
>   unit/itemconfig.rb:603
>   unit/itemconfig.rb:969
>
> IDENTICAL Matches found in :if (mass*3 = 621)
>   unit/itemconfig.rb:308
>   unit/itemconfig.rb:465
>   unit/itemconfig.rb:625
>
> IDENTICAL Matches found in :when (mass*2 = 612)
>   unit/itemconfig.rb:435
>   unit/itemconfig.rb:798
>
> Matches found in :when (mass = 572)
>   unit/itemconfig.rb:343
>   unit/itemconfig.rb:379
>   unit/itemconfig.rb:706
>   unit/itemconfig.rb:742
>
> IDENTICAL Matches found in :when (mass*2 = 564)
>   unit/itemconfig.rb:415
>   unit/itemconfig.rb:778
>
> IDENTICAL Matches found in :when (mass*2 = 540)
>   unit/itemconfig.rb:582
>   unit/itemconfig.rb:948
>
> Matches found in :when (mass = 500)
>   unit/itemconfig.rb:509
>   unit/itemconfig.rb:539
>   unit/itemconfig.rb:875
>   unit/itemconfig.rb:905
>
> IDENTICAL Matches found in :when (mass*2 = 492)
>   unit/itemconfig.rb:569
>   unit/itemconfig.rb:935
>
> Matches found in :when (mass = 452)
>   unit/itemconfig.rb:365
>   unit/itemconfig.rb:401
>   unit/itemconfig.rb:728
>   unit/itemconfig.rb:764
>
> IDENTICAL Matches found in :or (mass*4 = 416)
>   unit/itemconfig.rb:308
>   unit/itemconfig.rb:672
>   unit/itemconfig.rb:1038
>   unit/itemconfig.rb:1049
>
> Matches found in :when (mass = 404)
>   unit/itemconfig.rb:314
>   unit/itemconfig.rb:677
>
> Matches found in :when (mass = 380)
>   unit/itemconfig.rb:528
>   unit/itemconfig.rb:558
>   unit/itemconfig.rb:894
>   unit/itemconfig.rb:924
>
> IDENTICAL Matches found in :if (mass*2 = 336)
>   unit/itemconfig.rb:672
>   unit/itemconfig.rb:827
>
> IDENTICAL Matches found in :when (mass*2 = 124)
>   unit/itemconfig.rb:431
>   unit/itemconfig.rb:794
>
> Matches found in :when (mass = 84)
>   unit/itemconfig.rb:182
>   unit/itemconfig.rb:192
>   unit/itemconfig.rb:207
>
> IDENTICAL Matches found in :lasgn (mass*2 = 76)
>   unit/itemconfig.rb:458
>   unit/itemconfig.rb:821
>
> Matches found in :attrasgn (mass = 68)
>   unit/itemconfig.rb:302
>   unit/itemconfig.rb:638
>   unit/itemconfig.rb:661
>   unit/itemconfig.rb:1009
>
> IDENTICAL Matches found in :and (mass*2 = 68)
>   unit/itemconfig.rb:649
>   unit/itemconfig.rb:1020
>
> Matches found in :when (mass = 64)
>   unit/itemconfig.rb:175
>   unit/itemconfig.rb:185
>
> Matches found in :call (mass = 32)
>   unit/itemconfig.rb:213
>   unit/itemconfig.rb:224
>
> Matches found in :if (mass = 32)
>   unit/itemconfig.rb:156
>   unit/itemconfig.rb:264