mascip has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,
I create my modules with Module::Starter (for example My::Example).
My question is about how to automatize adding one class to an existing module. I would like to type

perl add_a_new_class_to_current_module.pl My::Example::Class
and have all folders and files created, as well as the boilerplates adapted.

For example to add My::Example::Class in the My-Example module, here is what i do by hand; how can i automate it? Each time i want to do this, i create a few directories and files, all by hand (or copy-paste and rename them) :

./lib/My/Example/Class.pm ./t/My/Example/Class/01_unit_test.t
and then modify the boilerplate code.
~ Edit : i just realized that Module::Starter::Smart can help with this. But when i try to use it in Windows XP, it seems to not understand that it should just add a module to the distro. It creates a new distro instead. I might not have set it up correctly - i added this line the the module-starter config file: plugin: Module::Starter::Smart . But anyway, i want to automatize more than just this :

After that, i add some custom Log::Log4perl logger code in a log/loggers.conf file, as well as in the two previous (.pm and .t) files.

I also often create a Test data builder class for new classes, in

./t/lib/My/Example/Class/Builder.pm
It inherits from Example::Class, and just adds a few subroutines to make tests easier to write, without having to add these subroutines to the original class.

~ ~ ~
It's all very little things, but they add up and i wonder whether i should make a script to do all of this from me.

But first, what are the existing tools that can help me make this process easier ? Can Module::Starter help me with this ? Or any other module ?

I'm considering starting to use Dist::Zilla. Could it help with this ? I guess, some boilerplate won't have to be written anymore, as plugins will add them to all of my classes. What about the folder and file creations?

I'm aware that for custom things like editing my log4perl configuration file, i will have to write my own scripts, but it's so smBut any help from existing modules would be welcome.

Cheers =)

Replies are listed 'Best First'.
Re: Adding a class to a module - Can Module::Starter or Dist::Zilla help?
by kcott (Archbishop) on Aug 12, 2012 at 08:43 UTC
    "But when i try to use it in Windows XP, it seems to not understand that it should just add a module to the distro. It creates a new distro instead. I might not have set it up correctly ..."

    Please show your .module-starter/config file and the full command you used. Without this, we can't tell if the setup is correct or if you used it correctly. For instance, modules have colons (e.g. --module=Some::Class) whereas distros have a hyphen (e.g. --distro=Some-Class) - perhaps those got mixed up on your commandline.

    While I appreciate that your question specifically asks about "adding to an existing module", I'll just point out that you can create multiple modules in a single distribution without using any plugins, e.g.

    module-starter --module=My::Example,My::Example::Class --distro=My-Exa +mple

    Using the plugin Module::Starter::Smart, I can run

    module-starter --module=My::Example

    My::Example has boilerplate with author and email (from config). I added a little POD text (to later check this wasn't being overwritten) and ran

    module-starter --module=My::Example::Class --distro=My-Example

    My::Example was not overwritten and My::Example::Class has boilerplate with author and email (from config).

    This appears to cover your "... have all folders and files created, as well as the boilerplates adapted." requirement.

    For your specific customisations (e.g. logger code), perhaps consider writing your own plugin. You may find Module::Starter::Plugin and Module::Starter::Plugin::Template to be useful if you choose to do this. Taking a look at the source of existing plugins (e.g. Module::Starter::Smart and Module::Starter::PBP) may also be helpful.

    I noticed that Module::Starter::Smart has:

    UPDATE: This plugin only covers the simplest use cases. For advanced usage, check out Module::Starter::AddModule.

    I'm not familiar with that module - it may be of use to you.

    -- Ken

      Thank you, i will try and use Module::Starter::Plugin or its Template API. The POD documentation is quite short, i'll try and tweak it around.

      I will try and use Module::Starter::Smart again, right now, and comment what i'm doing (on a Windows XP OS).

      First of all, here is my C:/Dropbox/.module-starter/config file :

      author: mascip email: example@gmail.com builder: Module::Build plugin: Module::Starter::Smart plugins: Module::Starter::PBP template_dir: C:\Dropbox\.module-starter\PBP

      If you think that not using the PBP plugin, i could just take it off the configuration file, and do all of this again.

      Now, i use module-starter

      C:\>module-starter --distro=My-Example --module=My::Example::Class --m +odule=Other::Example configdir : C:\Dropbox\.module-starter configdir : C:\Dropbox\.module-starter Added to MANIFEST: Build.PL Added to MANIFEST: Changes Added to MANIFEST: ignore.txt Added to MANIFEST: lib/My/Example/Class.pm Added to MANIFEST: lib/Other/Example.pm Added to MANIFEST: MANIFEST Added to MANIFEST: README Added to MANIFEST: t/00.load.t Added to MANIFEST: t/perlcritic.t Added to MANIFEST: t/pod-coverage.t Added to MANIFEST: t/pod.t Created starter directories and files
      Now my distro is created, and i check in the C:/My-Example/My/Example/Class.pm file that the boilerplate is as expected. It is. In the code i can read
      =head1 AUTHOR mascip C<< <example@gmail.com> >
      which shows that my configuration file did its job (i changed the email address to example@gmail.com, just before starting this example).

      Now it's time to try and use Module::Starter::Smart, which was included in the configuration file as you can see above.

      C:\>module-starter --distro=My-Example --module=My::Example::TheNewCla +ss configdir : C:\Dropbox\.module-starter configdir : C:\Dropbox\.module-starter My-Example already exists. Use --force if you want to stomp on it.
      It doesn't work as expected.

      Now i try it the other way around, giving the --module argument before --ditro, and obtain the same result :

      C:\>module-starter --distro=My-Example --module=My::Example::TheNewCla +ss configdir : C:\Dropbox\.module-starter configdir : C:\Dropbox\.module-starter My-Example already exists. Use --force if you want to stomp on it.

      And finally, if i go in my distro's directory, and try to create a module, then a get a whole new distro inside my first distro:

      C:\>module-starter --distro=My-Example --module=My::Example::TheNewCla +ss configdir : C:\Dropbox\.module-starter configdir : C:\Dropbox\.module-starter My-Example already exists. Use --force if you want to stomp on it.

      Did i do anything wrong?

        Nothing you have here leaps out at me as being wrong.

        I had a dig around in some of the source code. Module::Starter::PBP inherits from Module::Starter::Simple. It is Module::Starter::Simple's create_basedir() method that generates the "... already exists.  Use --force if you want to stomp on it." message. As far as I can see, you can't use Module::Starter::PBP to add a module to an existing distribution - I'm happy to be contradicted on that if someone knows a way to do it.

        None of the examples in my original reply used Module::Starter::PBP. You may find excluding that plugin fixes the immediate problem but I wouldn't really consider that a particularly good solution. You could subclass Module::Starter::PBP and write your own create_basedir() method - that's just a suggestion, there may be other implications which you should look into first.

        -- Ken

Re: Adding a class to a module - Can Module::Starter or Dist::Zilla help?
by Khen1950fx (Canon) on Aug 12, 2012 at 04:53 UTC
    First, I'm a die-hard h2xs guy; however, if I were to use module-starter, then I would use the default ExtUtils::MakeMaker.
    module-starter --module=My::Module --author=joe jones \ --email=joe.jones@example.com --builder=ExtUtils::MakeMaker
    Fix, then run Makefile.PL, and then run
    make manifest make make test make install make dist
    Now to add a new class, add your class lib, then delete the pm_to_blib file. Rerun make, make manifest, and make dist. Whew! It's harder than I thought to explain it in simple English, but I hope that it makes some sense.

      Hi and thank you for you answer :o)

      I know how to add a class to a module, but i'd like to automatize it. For example to type

      perl add_a_new_class_to_current_module.pl My::Example::Class
      and have the folders and files created, as well as the boilerplates adapted. Until now i've been creating folders and files by hand, and copy-pasting; and i don't like it.
      I made my first message a bit clearer, now.