Hello,
This looks like another use-case for extension methods in a day.
Extension methods in C# work are static methods defined anywhere, that
can be called like (instance) methods of some particular class or interface.
They would make perfect way for add-on libraries to provide convenience
methods for objects defined elsewhere. In .NET they are mainly used to
provide the "linq" methods to interfaces.
In C# extension methods are defined as static methods of any class, but
that seems to be because they were invented before C# allowed namespace-
scoped functions. So for Vala I'd suggest putting them in the namespace
the class is in or in a special "extend class".
Suppose there is interface Moo.IComparable, that looks like
namespace Moo {
interface IComparable : GLib.Object {
bool less_than(IComparable rhs);
}
}
Having one comparison allows defining the others in terms of the first
one. In Vala (unlike C#) interfaces can have implemented methods, but
suppose the library author forgot to define less_or_equal and you want
to define it and don't have control over the interface. So you'd define
extension method to add it. I propose following options for syntax:
namespace Moo {
bool less_or_equal(IComparable this lhs, IComparable rhs) {
return !rhs.less_than(lhs);
}
}
(the disadvantage here is that it has to be mangled to
moo_icomparable_less_or_equal, leading to a bit of overloading (another
less_or_equal with different "this" argument would be allowed))
namespace Moo {
bool icomparable_less_or_equal(IComparable this lhs, IComparable rhs) {
return !rhs.less_than(lhs);
}
}
(now the author needs to know the Vala mangling, because it's still supposed
to be called a.less_or_equal(b))
namespace Moo {
[lowercase_cprefix="icomparable_"]
class IComparableExtensions {
bool less_or_equal(IComparable this lhs, IComparable rhs) {
return !rhs.less_than(lhs);
}
}
}
(this is most C#-py, but requires either the c prefix annotation, or special
mangling rules)
namespace Moo {
[Extend]
interface IComparable {
bool less_or_equal(IComparable rhs) {
return !rhs.less_than(this);
}
}
}
(writing [Extend] to avoid new keyword, but that would be an option)
I probably like the last option best, but it's least like C#, so it depends
on how much similarity is desired.
I suppose extension properties should be possible with the limitation, that
they cannot have default implementation.
On Tue, February 9, 2010 22:44, pHilipp Zabel wrote:
>> I would suggest that adding vendor specific modifications to existing
>> classes is way too ugly
>
> Agreed.
Modifications are indeed ugly, but adding a couple of convenience methods
following the normal naming convention of methods for the class is IMHO OK.
>> to be accepted and you should bind it to hildon
>> classes. How can they even add more properties to an already defined
>> class?
>
> They ship a modified GTK+ library. Hildon depends on that.
> I guess we could get away with just binding the hildon_gtk_entry_*
> methods to Hildon.Entry instead of Gtk.Entry. Is there a way of doing
> this via metadata before the vapigen step?
> But there are a few others like hildon_gtk_widget_set_theme_size or
> hildon_gtk_window_set_progress_indicator that can't be mapped to
> Hildon classes, as they are needed to work on Gtk.Button and
> Gtk.Dialog, for example.
That's where extension methods would be useful. The hildon package would
just do
[cprefix="hildon_gtk"]
namespace Gtk {
[Extend] class Widget { ... set_theme_size(...); }
[Extend] class Widnow { ... set_progress_indicator(...); }
}
and
--
- Jan Hudec <[email protected]>
_______________________________________________
Vala-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/vala-list