James Laver james.laver at
Mon May 6 15:34:53 BST 2013

On 6 May 2013, at 13:57, "Th. J. van Hoesel" <th.j.v.hoesel at> wrote:
> What if people figured out that the method did accept 3 or more arguments (why and how.. because they dug into the code ?). It would make no sensense at all to call the method Number::Fraction->new( 1, 4, 6, 7, 2), but it would produce by some magic allowance that it should return a Number::Fraction object.

Okay, well first of all any constructor is going to take an arbitrary number of arguments. That's how argument passing in perl works. If they read the code they would see what it does, the only way they would otherwise see it taking more than two arguments is by attempting to pass them. And if they did that, they ought to have been reading the documentation more closely. Otherwise they did and they just decided to see what happens? I don't see that one myself.

> So, now we have some legacy code. And now extending the functionality in a natural understandable manner, might cause old programs that did very odd method calls to break.

I think you misunderstand here. How is what you propose a natural understandable manner? Positional parameters are by convention added to the end if you're creating more of them, not the front. See what messes libraries in other languages have gotten into by making that mistake (erlang springs to mind).

Furthermore, if programs are using the module aside from how it's documented, they deserve to be broken. They could have submitted a bug to make something official behaviour, but they didn't. And since we're talking about a simple fraction module here, I don't think we're going to find anyone doing something daft.

> Is my next approach acceptable:
> now:
> a quick patch that will issue a warning the moment the method is being called with 3 or more arguments (only once per application run), letting users know that they did some odd thing, but forgive them and continue.

Nondestructive. I don't think anyone would argue with this.

> next:
> implement a 3-argument methode that will only work properly when the modules is being used as
> use Number::Fraction qw{:mixed}
> still issue a warning

Why don't you just create a new constructor that takes arguments differently? This would seem to be a good way around it. Seems to me you're way overcomplicating things. It's also a common perl pattern because we're blessed with the ability to have as many constructors as we want.

> next:
> let the module die with unintended 3-plus-argument calls
> use Number::Fraction qw{:mixed}

Again, you're overcomplicating.

> next:
> drop the requirement to use :mixed, make it default
> all in a time frame of one year ?

Why on earth are you overcomplicating this so?

> Someone really need to enlighten me as to why write method implementations like this, that accept arbitrary arguments, rather than locking down the API

It's a dynamic language. We have documentation on how to do things. And extra arguments are ignored. This is fairly normal. I write a lot of code that does this too and i don't consider it broken. In fact, it's more or less a perl idiom and common to a lot of dynamic languages really (though in the majority of cases they just use named parameters because the language has native support for method signatures).

Ask yourself what you're achieving by changing the API like this. I think you've got the potential to break code and I don't think you're doing it for the right reasons. I don't like changing the order of positional parameters when you're adding new ones either because it confuses people.

Furthermore, I don't think what Dave is suggesting about the move to Moose is a daft one, but you'd do well to preserve the API as it currently stands. Perhaps a BUILDARGS method that checks if it's being called according to the old API (i.e. has two args, both of which are numeric) and fills in the keys for you if so? To get the new 'mixed' functionality, you'd just pass in the keys manually and it would do the right thing?


More information about the mailing list