File::Comments(3)
π NAME π
Okay bestie, welcome to File::Comments(3) β straight out of the User Contributed Perl Documentation, and it's giving main character energy π
File::Comments β recognizes file formats and extracts format-specific comments π
β¨ SYNOPSIS β¨
use File::Comments;
my $snoop = File::Comments->new();
# *----------------
# | program.c:
# | /* comment */
# | main () {}
# *----------------
my $comments = $snoop->comments("program.c");
# => [" comment "]
# *----------------
# | script.pl:
# | # comment
# | print "howdy!\n"; # another comment
# *----------------
my $comments = $snoop->comments("script.pl");
# => [" comment", " another comment"]
# or strip comments from a file:
my $stripped = $snoop->stripped("script.pl");
# => "print "howdy!\n";"
# or just guess a file's type:
my $type = $snoop->guess_type("program.c");
# => "c"
π¦ DESCRIPTION π¦
So here's the vibe: File::Comments looks at a file, figures out what type of file it is, works out which comment syntax that format uses, pulls out every single comment, and hands them back to you as a reference to an array of chunks. Or β if that's not your moment β it just strips all the comments out of a file instead. Choose your fighter π
Right now it supports Perl scripts, C/C++ programs, Java, makefiles, JavaScript, Python and PHP. Iconic lineup, no cap.
The plugin architecture is the whole reason this thing slays: adding a new format is genuinely easy. To support a new format you just install a new plugin module β you do not have to touch the File::Comments codebase at all, because new plugins get picked up automatically. Obsessed π«Ά
File::Comments can also just be used to plain guess a file's type, and it's somewhat more flexible than File::MMagic and File::Type. The tea: file types in File::Comments are typically based on file name suffixes (*.c, *.pl, etc.). But if there's no suffix available, or the suffix is ambiguous β like if several plugins all registered a handler for the same suffix β then the file's content gets used to narrow down the possibilities until it can arrive at a decision. Detective behaviour, lowkey π
WARNING: THIS MODULE IS UNDER DEVELOPMENT, QUALITY IS ALPHA. IF YOU FIND BUGS, OR WANT TO CONTRIBUTE PLUGINS, PLEASE SEND THEM MY WAY. π Bestie this is a real warning, not a cute one. Alpha quality means alpha quality. Found a bug? Send it over. Wanna contribute a plugin? Literally send it over.
πΈ FILE TYPES πΈ
Currently, the following plugins are included in the File::Comments distribution:
###############################################
# plugin type #
###############################################
File::Comments::Plugin::C c (o)
File::Comments::Plugin::Makefile makefile (X)
File::Comments::Plugin::Perl perl (X)
File::Comments::Plugin::JavaScript js (o)
File::Comments::Plugin::Java java (o)
File::Comments::Plugin::HTML html (X)
File::Comments::Plugin::Python python (o)
File::Comments::Plugin::PHP php (o)
(X) Fully implemented
(o) Implemented with regular expressions, only works for
easy cases until real parsers are employed.
The constants listed in the type column are the exact strings that the guess_type() method returns. Remember them, they're your keys π
π Methods π
π $snoop = File::Comments->new()
Creates a brand new comment extractor engine. It automatically initializes all the plugins for you, bestie. No manual labour.
Wanna avoid cold calls (see "Cold Calls" below)? Set cold_calls to a false value β it defaults to 1:
$snoop = File::Comments->new( cold_calls => 0 );
By default, if no plugin can be found for a given file, File::Comments will throw a fatal error and die(). If that's not the energy you're going for and you'd rather a default plugin step in, you can specify it in the constructor with the default_plugin parameter:
$snoop = File::Comments->new(
default_plugin => "File::Comments::Plugin::Makefile"
);
π $comments = $snoop->comments("program.c");
Extracts all the comments from a file. After it determines the file type β by suffix, or by content via "Cold Calls" β the comments get extracted as chunks and returned as a reference to an array.
Want one single string with all the comments in it instead? Just join the chunks:
my $comments_string = join '', @$comments;
π $stripped_text = $snoop->stripped("program.c");
Strips all comments from a file. After determining the file type by either suffix or content ("Cold Calls"), every comment is removed and the stripped text comes back to you in a scalar. Clean girl aesthetic β¨
π $type = $snoop->guess_type("script.pl")
Guesses the type of a file, based on either the suffix, or β in the absence of a suffix β via "Cold Calls". Returns the result as a string: "c", "makefile", "perl", etc. (see "FILE TYPES").
π $snoop->suffix_registered("c")
Returns true if one of the plugins has registered the given suffix. Simple as that π
π§ Writing new plugins π§
Writing a new plugin to add functionality to the File::Comments framework is as simple as defining a new module derived from the baseclass of all plugins, File::Comments::Plugin. You need three additional methods: init(), type(), and comments().
init() gets called when the mothership finds the plugin and initializes it. This is your moment to register the extensions that the plugin wants to handle π
The second mandatory method is type(), which returns a string indicating the type of the file examined. Usually you can do this without further ado, since a basic plugin will only be called on files it registered for by suffix. The exceptions to this get explained later.
The third method is comments(), which returns a reference to an array of comment lines. By the time comments() gets called, the content of the source file to be examined will be available in:
$self->{target}->{content}
And that's it. Here's a functional basic plugin, registering a new suffix .odd with the mothership and expecting files with comment lines that start with ODDCOMMENT:
###########################################
package File::Comments::Plugin::Oddball;
###########################################
use strict;
use warnings;
use File::Comments::Plugin;
our $VERSION = "0.01";
our @ISA = qw(File::Comments::Plugin);
###########################################
sub init {
###########################################
my($self) = @_;
$self->register_suffix(".odd");
}
###########################################
sub type {
###########################################
my($self) = @_;
return "odd";
}
###########################################
sub comments {
###########################################
my($self) = @_;
# Some code to extract all comments from
# $self->{target}->{content}:
my @comments = ($self->{target}->{content} =~ /^ODDCOMMENT:(.*)/);
return \@comments;
}
1;
π§ Cold Calls π§
If a file doesn't have an extension, or has an extension that's served by multiple plugins, File::Comments will go shop around and ask all the plugins if they want to handle the file. The mothership calls each plugin's applicable() method, passing it an object of type File::Comments::Target, which contains the following fields:
π and then the original page just... doesn't list them. Not one field. We're left on read. Anyway, moving on bestie.
When a plugin gets such a cold call (indicated by the third parameter to applicable()), it can either accept or deny the request. To arrive at a decision, it can peek into the target object. The Perl plugin illustrates this:
###########################################
sub applicable {
###########################################
my($self, $target, $cold_call) = @_;
return 1 unless $cold_call;
return 1 if $target->{content} =~ /^#!.*perl\b/;
return 0;
}
If a plugin doesn't define an applicable() method, a default method is inherited from the base class File::Comments::Plugin, which looks like this:
###########################################
sub applicable {
###########################################
my($self, $target, $cold_call) = @_;
return 0 if $cold_call;
return 1;
}
This will deny all cold calls and only accept requests for files with suffixes or base names the plugin has already signed up for. Boundaries, honestly π
π Plugin Inheritance π
Plugins can reuse existing plugins by inheritance β yes, it's giving generational wealth π For example, if you wanted to write a catch-all plugin that takes over all cold calls and handles comments like the Makefile plugin, you can simply use:
###########################################
package File::Comments::Plugin::Catchall;
###########################################
use strict;
use warnings;
use File::Comments::Plugin;
use File::Comments::Plugin::Makefile;
our $VERSION = "0.01";
our @ISA = qw(File::Comments::Plugin::Makefile);
###########################################
sub applicable {
###########################################
my($self) = @_;
return 1;
}
File::Comments::Plugin::Catchall just implements applicable() and inherits literally everything else from File::Comments::Plugin::Makefile. The way that it does the absolute bare minimum and still eats π
β LEGALESE β
Copyright 2005 by Mike Schilli, all rights reserved. This program is free software, you can redistribute it and/or modify it under the same terms as Perl itself.
π AUTHOR π
2005, Mike Schilli <cpan@perlmeister.com>
and that's the whole page bestie!! π¦ no cap, that was File::Comments(3), from perl v5.42.0, dated 2025-07-25, filed under User Contributed Perl Documentation. periodt π
β¨
π¦ where this page comes from
- fedora 43: perl-File-Comments 0.08-43.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms