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. :)
Please don't break backwards compatibility. If you did a web search, you'd have found plenty of people using the existing functional interface.
Hmm... I do see a few usages of it. However, this creates a very annoying situation for maintaining this.
I'll consider this further.
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?
Now they're not? Really? That's incorrect and I don't think you should say that. It hasn't changed yet, it is still possible to use it the way you wrote.
I've explained in the blog post why I want to break this: supporting both is quite a hassle which I prefer not to deal with.
However, since the first comment mentioned many people use it in a functional way, I looked into it and decided for now to keep the backwards compatibility. I've reverted those specific changes and will release a new non-deprecating version later on.
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.
This is *one* way to do it, not the *only* way, and I appreciate you mentioning it. Considering all my attempts until now were to prevent core changes, this was done in a different way, which was harder to maintain, and definitely not as fun.
I've considered how to do it and I might choose this path or continue to support the way it was originally done. This is besides the point though. When someone asked kindly that I continue to support it, I decided to do it.
I'll be honest, since I really do not like the way people choose to comment online, if it weren't for the first comment here, I probably wouldn't continue to support it, and I would respond to your "things used to be easy" with "sucks for you, I don't care".
People need to learn to be a little more respective, even when online.
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'll be able to maintain functionality and keep it supporting both, thanks to some of the refactoring I've done recently.
I didn't think it was that important, but apparently it is, so I'll make sure to backward support it.
I think it's important to know that being disrespectful or impolite to someone might result in such a response.
SDD (Spite-Driven Development) and FDD (Feelings-Driven Development) are radically effective new methodologies.
Available at your local book stores soon! :)
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.