
strategies to uncouple internal dependencies on functions (and packages)
========================================================================

&database::DbPlain::PlainToTable
  liest *.csv in array of hashes (o.ä.), Spaltenbezeichner werden aus dem
  Header gelesen.  A replacement (AH data structure) can be found in
  ~/mailw/201105261553_PfamRelSignif.pl .

&MainLib::Cmdline::GetWriteHandle($file)
  ==(mostly like)==> FileHandle->new($file,'w')

MainLib::DefaultObjArray
  provides the standard constructor framework new() and the abstract method
  ini().  A replacement is easy if the derived object provides its own
  constructor definition(s). A stump would be:

  sub new {
    bless (my $this=[]);
    my (undef,@arg) = @_;
    return $this->ini(@arg);
  }
  sub ini { return shift() }

MainLib::DefaultObjHash
  provides the standard constructor framework new(), the abstract method
  ini(), and a function (&_LocalSwitch) to get a hash of switches that are
  locally active - possibly not required for an isolated derivative of the
  code.  A replacement is easy if the derived object provides its own
  constructor definition(s). A stump would be:

  sub new {
    bless (my $this={});
    my (undef,@arg) = @_;
    return $this->ini(@arg);
  }
  sub ini { return shift() }

&MainLib::File::FileCopy
  Just framework/wrapping around &File::Copy::copy. Core functionality resides
  in that function.

&MainLib::File::WriteFile
  writes string (arg2) to file (arg1). Should be easy to uncouple this, or
  just to implement a shortcut version of that function.

&MainLib::Misc::MySub => "(caller(0))[3]"

&MainLib::Path::PathLinkResol($path)
  Simpler variant to process an absolute path string, still requiring
  &PathExpand:

  # resolve symbolic link to physical path
  sub PathLinkResol {
    my @psplit = split </+>, &PathExpand(shift());
    my ($path,%pok,%lndone);

    # grow path via adding split by split
    while (defined (my $pfrag = shift @psplit)) {
      $path .= (defined($path) ? '/':'') . $pfrag;
      if (!length($path) or $pok{$path}) { next }

      # found link
      if (-l $path) {
        # looped link - unable to resolve
        if ($lndone{$path}) { $path=~s<^(.+)/[^/]+$><$1>; next; }

        # resolve link
        $lndone{$path} = 1;
        my $lntgt = readlink ($path);
        $path = &PathExpand ($lntgt,-cwd=>&dirname($path));

        # restart split/resolution
        unshift @psplit, split(/\/+/,$path);
        undef $path;
        next;
      }

      # path is physical until now
      $pok{$path} = 1;
    }

    return $path;
  }

&MainLib::Path::Unbuffer($fhandle)
  a `do{ select $fhandle; $|=1; }' will work in most cases. A more conservative,
  but compact, implementation can be found in BiblCards.pl, package litcards.

&MainLib::Path::PathExpand($path)
  a `($path=~m<^/>) ? $path : &Cwd::cwd().'/'.$path' will work in most cases.
  If option behavior must be reproduced, a minimal solution looks like

  sub PathExpand {
    my ($path,%opt) = @_;
    return ($path=~m<^/>) ? $path : ($opt{-cwd}||&Cwd::cwd()).'/'.$path;
  }

&MainLib::Path::PathPhysical($path)
  # *** obsolete ***
  use &Cwd::realpath

&MainLib::Path::PathSplit($file)->{name}
  => &File::Basename::basename($file)
&MainLib::Path::PathSplit($file)->{dir}
  => &File::Basename::dirname($file)

&MainLib::StrRegexp::TimeStr
  [additional dependencies? Interface to POSIX module]

&Math::kCalc::Max
&Math::kCalc::Min
  Short implementation (for stand-alone script) can be found at many places

&Math::kCalc::Mean
  Short implementation (for stand-alone script) can be found at many places

&Math::kCalc::SignChar
  Short implementation (for stand-alone script) can be found in package
  tscriptaln, script blockalignflat_aln.pl (as &signc)

&Math::kCalc::Sum
  Short implementation (for stand-alone script) can be found at many places

&Math::kRandom::RandStr
  As a one-line script:

  perl -e 'BEGIN{ our @carr=(q(a)..q(z),q(A)..q(Z),0..9) } $n=shift()||1; for ($i=0;$i<$n;++$i){ $s.=$carr[rand(int(@carr))] } print $s,qq(\n)'

&Math::kRandom::RandArrayOrder
  Implementation is quite compact and without further dependencies.
  However, a stand-alone script version can be found in
  workpkg 201608291500_CFBI_7_MS, script Human_GeCKOv2_target_residual.pl .

&Math::Sort::ListLocateSorted
  leaf node in chain of dependencies
  Shorter implementation (for stand-alone script) can be found in
  tuple_diagbayes/tuple_diagbayesvst_accur.pl .

&Math::Statist::GaussVal
  A short implementation can be found in a benchwork project
  ~20140624 ("polya*").

&SeqLab::SeqBench::SeqStrPure
  leaf node in chain of dependencies
  In most stand-alone cases, the following definition will work

  sub SeqStrPure {
    my ($sSeq) = @_;
    $sSeq =~ tr/abcdefghiklmnpqrstuvwxyABCDEFGHIKLMNPQRSTUVWXY//cd;
    return $sSeq;
  }

&SeqLab::SeqBench::SeqstrRevcompl
  leaf node in chain of dependencies
  Shorter implementation (for stand-alone script) can be found in
  miRNA/pipeline/extract_mirna.pl

&SeqAlign::Align::AlnClustalRead
  A simple wrapping implementation can be found in alnsuite/aln2mfa.pl .
  A stand-alone implementation can be found in alnsuite/alnconcat.pl .

&SeqAlign::Align::AlnClustalSprint
  A break-down to a stand-alone, instant-print function can be found in
  alnsuite/alnconcat.pl .

&SeqAlign::Align::AlnGapdirShift
  A shorter, very close implementation (for stand-alone script) can be found in
  ScriptGAP4/GapAnalPcrhaplo.pl, function &read_aln_gapdir .

&SeqAlign::Align::AlnMargins
  A break-down to a stand-alone function can be found in alnsuite/alnconcat.pl .

&SeqAlign::AlnProj::AlnprojGapdirOpen
  Shorter implementation (for stand-alone script), resulting in SeqAlign::Align
  data structure, can be found in ScriptGAP4/GapAnalPcrhaplo.pl, function
  &read_aln_gapdir .

&SeqAlign::AlnProj::AlnprojGet
  A simple implementation getting around the complex Alnproj data structure
  can be found in alnsuite/aln2mfa.pl .
