Updates to Sys::HostIP

Sys::HostIP simply parses ifconfig/ipconfig (supports GNU/Linux/BSD/Windows) and gives you the interfaces and IPs found.

I stumbled upon this module when I was looking for a way to clean get all the ips of every interface on machines at $work. I needed something that parses ifconfig cleanly, because I didn't want to do it myself. I found a few and Sys::HostIP was by far the easiest, simplest, fastest and the one I decided to use. I noticed a few bugs open and contacted the author who gave me co-ownership. I since updated it and cleaned most of the ticket pool.

I've recently stumbled another situation, in which I want to find the IPs by order. Thinking I could just tweak the module to allow fetching it in order, I found that the logics is a bit of a mind boggle. I retained much of the original code and it supported both functional programming (as in functions) and object oriented, and I wanted to keep that.

I started by mapping on my board at $work all of the paths that methods and functions take. This was a total mess and I decided it's time to pick one or the other. I've picked object oriented in order to save user configurations, allow results caching, reserve status and have reusability.

This means that the next release of Sys::HostIP will warn when the functional interface will be used, and the release after that (version 2.00) will have it removed completely. I intend to have that release in at least two weeks from today, perhaps even a month.

Another important change is that Taint mode actually works now. Previous the regex parsing used to get the binary directory (for setting the PATH environment) was wrong, and I removed it in favor of the core module File::Basename.

I also removed the need for Test::TinyMocker and Test::Exception. This makes the module have zero non-core depdendencies. Hey, why not?

Feedback is welcome.

Thanks goes to Joel Berger, Yanick Champoux and Gabor Szabo for spreading the idea of promoting our distribution, and actually doing it. :)

15 Comments

Please don't break backwards compatibility. If you did a web search, you'd have found plenty of people using the existing functional interface.

Things used to be easy with this module:

$my_ip = ip();
$ips = ips();
$ifs = interfaces();
# cache these things however I want.

Now they're not. Why break this?

I don't see how it's a hassle. You can put all the object-y stuff in Sys::HostIP::OO, then do this in Sys::HostIP:

sub new {
# whatever argument processing...
bless $obj, 'Sys::HostIP::OO';
}

sub ip { __PACKAGE__->new->ip }
sub ips { __PACKAGE__->new->ips }
sub interfaces { __PACKAGE__->new->interfaces }

Done.

Once a new maintainer helps an aging module to modernize, that maintainer might have to make necessary choices, so that might even break backwards compatibility. This must be allowed to happen (with an appropriate deprecation cycle).

This is open source software; new maintainers of old modules are the life-breath which keeps it working. Of course we in the Perl community prefer back compat, but when an author chooses to make that tough choice, either offer to help (no one had taken the module previously), fork, or make due.

Perhaps a minimal set of functionality can be kept with functional wrappers? Will those people who want it offer to maintain it?

I would respond to your "things used to be easy" with "sucks for you, I don't care".
That's good to know.

SDD (Spite-Driven Development) and FDD (Feelings-Driven Development) are radically effective new methodologies.

So I started playing with Sys::HostIP today on Windows 7 and I couldn't help but wonder why I kept getting these warnings since Sys::HostIP works with Windows.

Unknown system (MSWin32), guessing ifconfig is in /sbin/ifconfig (email xsawyerx@cpan.org with the location of your ifconfig)
at hostip.pl line 4

So I looked at the code. _get_ifconfig_binary doesn't have a check for MSWin32|cygwin like _get_interface_info does.

You could add a Windows check into _get_ifconfig_binary. Or you could remove the call to _get_ifconfig_binary from new and simply call _get_interface_info from within _get_unix_interface_info.

Sawyer – I don’t want to excuse the rudeness, but please be aware that you brought it onto yourself. Changing the published interface of a module, even one that has not seen updates in years, is by and large a no-no.

If people have code that relies on the module (or they’ve been using it in one-liners or what have you, for ways of depending on it), then breaking the interface means pulling the rug out from under them while they were in the middle of other work.

It should be quite understandable that people get cranky when you do that to them. In a perfect world they wouldn’t just let out that reaction without a filter; but in a perfect world you wouldn’t have given them reason for it either. :-)

(Now there’s some discussion that can be had here about whether they should expect this in the first place; after all, the software is libre and gratis, so if it breaks they get triple their money back. But I point this out merely to note that I am aware of subtleties – I don’t want to complicate the basic issue, since the whether or not one may have a reasonable expectation not to be inconvenienced makes no difference to the fact that one has been inconvenienced.)

If I’ve learned one thing about the design of interfaces across time, it’s this: if you want to change an interface in some other way than adding to it, then change the namespace. (And because this is costly and gets exponentially more costly with every time it happens: think very hard about whether you need and want to make such changes at all.) Whether we’re talking about Perl modules, classes in any language, XML vocabularies, or anything else, I have found this rule to be universally true.

"You could add a Windows check into _get_ifconfig_binary. Or you could remove the call to _get_ifconfig_binary from new and simply call _get_interface_info from within _get_unix_interface_info."

I think I meant:
You could add a Windows check into _get_ifconfig_binary. Or you could remove the call to _get_ifconfig_binary from new and simply call _get_ifconfig_binary from within _get_unix_interface_info.

Leave a comment

About Sawyer X

user-pic Gots to do the bloggingz