Disclaimer

The content of this blog is my personal opinion only. Although I am an employee - currently of Nvidia, in the past of other companies such as Iagination Technologies, MIPS, Intellectual Ventures, Intel, AMD, Motorola, and Gould - I reveal this only so that the reader may account for any possible bias I may have towards my employer's products. The statements I make here in no way represent my employer's position, nor am I authorized to speak on behalf of my employer. In fact, this posting may not even represent my personal opinion, since occasionally I play devil's advocate.

See http://docs.google.com/View?id=dcxddbtr_23cg5thdfj for photo credits.

Friday, December 11, 2015

I dislike Perl's lib/Module.pm AND lib/Module/SubModule.pm

I dislike how Perl requires modules, and the submodules which are really "internal" to them, to live in two places in the filesystem - even if those places are right next to each other.

E.g. the module's top level code in some lib/Module.pm

And the code for any submodules that are really part of the module in the directory tree under lib/Module, e.g. lib/Module/SubModule.pm

So you cannot simply operate on one filesusem object for the module: e.g.g you cannot do:

mv lib/Module some-other-lib-path/Module

Instead, you must do
mv lib/Module.pm some-other-lib-path/Module.pm
mv lib/Module.pm some-other-lib-path/Module.pm 
A minor difference, two commands rather than one, something that can odten be patched over by regexps.

But an important difference: I would go so far as to say that the representation of Perl modules (classes) in the filesystem is not object oriented.  I would say that one of the key characteristics of an object, in this class treating the code for a class as an object, is that it behaves like it is a single object, unless explicitly opened up to look inside.

---+ Bad Influence on Perl CPAN class structure

I think this decision, to have lib/Module.pm and lib/Module/SubModule.pm, has had a bad, or at least confusing, influence on CPAN's module structure.

Sometimes a CPAN module Foo::Bar (lib/Foo/Bar.pm) is actually a module completely unrelated[*] to module Foo (lib/Foo.pm). More confusing if module Foo actually has some internal modules Foo::Fu (lib/Foo/Fu.pm).

(Note *: OK, not "completely unrelated".  How about "unrelated wrt code structure", or "related only by topic, but not actual code".)

Then there is no localization of Foo in the filesystem.   Some parts of lib/Foo are part of module Foo, and some are not.   And not everthing in module Foo is under lib/Foo.

I.e. the Perl CPAN filesystem structure sometimes reflects module structure, and sometimes it just reflects theme.

---+ Kluges

For this reason, I often make my modules appear as Foo::Foo, i.e. lib/Foo/Foo.pm.

But this can become tiresome.  Tiresome. Repetitious.  And it does not prevent somebody else from defining Foo::Bar, and wanting to live in the same directory tree (if not in separate PATH elements).

So I might try Topic::Long_Module_Name_Unlikely_To_Conflict::Short_Module_Name

i.e.
      lib
           /TopicLong_Module_Name_Unlikely_To_Conflict
               /Short_Module_Name.pm
               /Short_Module_Name/Sub_Modules...

e.g.  lib/Foo/AG_Foobar/Foo.pm

Not ideal.

Similarly, I might use a level of indirection to group internal submodules

Foo::internal::Submodules
vs
Foo::Unrelated_Submodules

Again, not ideal.    

---+ What is really needed

Modules should correspond to subtrees of the filesystem.

e.g. lib/Foo.pm, if no furter structure.

lib/Foo.pmdir/Foo.pm  if submodules such as lib/Foo.pmdir/Sub.pm

with it being an error to have both lib/Foo.pm and lib/Foo.pmdir exist.

Or, if you will, require the indirection even if no further structure: lib/Foo.pmdir/Foo.pm, and never lib/Foo.pm

The main file might be called lib/Foo/main.pm.  But I rather like lib/Foo/Foo.pm, or lib/Foo.pmdir/Foo.pm





---+ References

use - perldoc.perl.org: <>

require - perldoc.perl.org: <The require function will actually look for the "Foo/Bar.pm" file in the directories specified in the @INC array.>>



'via Blog this'

Finally got emacs compilation-error-regexp working for perl CPAN Test::Unit::TestCase

Summary: Finally got emacs compilation-error-regexp working for perl CPAN Test::Unit::TestCase



Not only did I need to add a regexp,
but I also needed to disable a compilation-mode-font-lock-keywords pattern
- apparently there may be some phase ordering.

This woukd be more reliably if there were the ability to return ALL possible substrings matching a regexp,
as opposed to being maximally or minimally greedy.

    ;; adding patterns to compilation-error-regexp-alist and/or compilation-error-regexp-alist
    ;; to try to get a perl CPAN Test::Unit error message, like

    ;; There were 3 failures:
    ;; 1) TestCases_for_FrameMaker_MIF_AG.pm:875 - test_another_error(TestCases_for_AG_FrameMaker_MIF)
    ;; expected '', got 'deliberate mismatch'
    ;;
    ;; 2) TestCases_for_FrameMaker_MIF_AG.pm:879 - test_yet_another_error(TestCases_for_AG_FrameMaker_MIF)
    ;; expected '', got 'deliberate mismatch'
    ;;
    ;; 3) TestCases_for_FrameMaker_MIF_AG.pm:898 - test_special_stuff__format_tuple_to_MIF_string__Cell_context__WIP(TestCases_for_AG_FrameMaker_MIF)

    (require 'compile)

    (add-to-list 'compilation-error-regexp-alist
'("\nThere were [0-9]+ failures:\n1) \\([a-zA-Z0-9_.-.---]+\\):\\([0-9]+\\) - test_"
  1 2)
    (add-to-list 'compilation-error-regexp-alist
'("\n[0-9]+) \\([a-zA-Z0-9_.-.---]+\\):\\([0-9]+\\) - test_"
  1 2)
      )
    (if nil  ;; the regexp below causes compilation-error-regexp-alist to stop working completely - no matching
      (add-to-list 'compilation-error-regexp-alist
'("\nThere were [0-9]+ failures:\n1) .*\\(\\w\\|\\W)*\n[0-9]+) .*\\(test_\\)"
  2)
)
      )


Diffs:


    === modified file '.emacs'
    *** .emacs 2015-12-12 00:18:53 +0000
    --- .emacs 2015-12-12 00:26:30 +0000
    ***************
    *** 4129,4139 ****
     ;; perl CPAN Test::Unit
     ;; 1) TestCases_for_FrameMaker_MIF_AG.pm:763 - test_special_stuff_to_insert_wip(TestCases_for_AG_FrameMaker_MIF)
     '(("\\([a-zA-Z0-9_.-.---]+:[0-9]+\\)"
    !      ;;(0 'compilation-line-face nil t)
    !      ;; (0 'ag-test-result-unexpected) ;; works (modulo filename matching)
    !      ;;(1 'ag-test-result-unexpected) ;; works (modulo filename regexp
    !      (1 compilation-line-face nil t)
    !      ))
     '(("expected\s+.*got\s+.*"
 (0 'ag-test-result-unexpected)
 ))
    --- 4129,4139 ----
     ;; perl CPAN Test::Unit
     ;; 1) TestCases_for_FrameMaker_MIF_AG.pm:763 - test_special_stuff_to_insert_wip(TestCases_for_AG_FrameMaker_MIF)
     '(("\\([a-zA-Z0-9_.-.---]+:[0-9]+\\)"
    ! ;;      ;;(0 'compilation-line-face nil t)
    ! ;;      ;; (0 'ag-test-result-unexpected) ;; works (modulo filename matching)
    ! ;;      ;;(1 'ag-test-result-unexpected) ;; works (modulo filename regexp
    ! ;;      (1 compilation-line-face nil t)
    ! ;;      ))
     '(("expected\s+.*got\s+.*"
 (0 'ag-test-result-unexpected)
 ))
    ***************
    *** 4628,4637 ****
      (add-to-list 'compilation-error-regexp-alist
 '("\nThere were [0-9]+ failures:\n1) \\([a-zA-Z0-9_.-.---]+\\):\\([0-9]+\\) - test_"
    1 2)
)
    ! (if nil
(add-to-list 'compilation-error-regexp-alist
    !     '("\nThere were [0-9]+ failures:\n1) .*\\(\\w\\|\\W)*\n[0-9]+) \\([a-zA-Z0-9_.-.---]+\\):\\([0-9]+\\) - test_) "
    !        2 3)
 )
)
    --- 4628,4640 ----
      (add-to-list 'compilation-error-regexp-alist
 '("\nThere were [0-9]+ failures:\n1) \\([a-zA-Z0-9_.-.---]+\\):\\([0-9]+\\) - test_"
    1 2)
    + (add-to-list 'compilation-error-regexp-alist
    +     '("\n[0-9]+) \\([a-zA-Z0-9_.-.---]+\\):\\([0-9]+\\) - test_"
    +        1 2)
)
    ! (if nil  ;; the regexp below causes compilation-error-regexp-alist to stop working completely - no matching
(add-to-list 'compilation-error-regexp-alist
    !     '("\nThere were [0-9]+ failures:\n1) .*\\(\\w\\|\\W)*\n[0-9]+) .*\\(test_\\)"
    !        2)
 )
)