[stringtemplate-interest] IAttributeRenderer and Type Inheritancein C#
Jonathan Buhacoff
jonathan at buhacoff.net
Thu Oct 22 14:20:58 PDT 2009
On Oct 22, 2009, at 12:23 PM, Vincent DARON wrote:
> I'm quite new to StringTemplate, the first need for that feature was
> internationalization of Enumerations
>
I know you're not using Java... In Java this is easy with
ResourceBundle. Find or make the equivalent in your platform ; this
doesn't require a modification to StringTemplate.
> (All Types starting with "My" are custom classes here to ease reading)
>
> I simply try to do
>
> StringTemplate.SetAttributeRenderer(typeof(Enum),new
> MyI18nEnumRenderer());
>
> It did'nt works and I had to do
>
> StringTemplate.SetAttributeRenderer(typeof(MyEnum1),new
> MyI18nEnumRenderer());
> StringTemplate.SetAttributeRenderer(typeof(MyEnum2),new
> MyI18nEnumRenderer());
> StringTemplate.SetAttributeRenderer(typeof(MyEnum3),new
> MyI18nEnumRenderer());
> ...
>
> The second need for that feature was for Formatting purposes
>
> StringTemplate.SetAttributeRenderer(typeof(IFormatProvider),new
> MyFormatProviderRenderer());
>
You can create a new type MyFormattedType that implements your
IFormatProvider interface. Then register your
MyFormatProviderRenderer renderer for MyFormattedType. Then wrap all
your types that implement IFormatProvider with a MyFormattedType type
object. That will do what you want, and after you set it up once it's
easy to reuse.
> did'nt works either...
>
> It's after that second problem that I looked into Sources and
> propose my approach.
>
> I do not think that it could be a speed problem, with a behavior
> like mine, people using AttributeRenderer will probably use less
> Renderer. The problem about priority is a little more embarrassing.
> Maybe using 2 lists instead of a Dictionary (Type and Renderer) ?
> People are adding AttributeRenderer in the order they will be
> processed.
No, people are adding AttributeRenderers in any order because they go
in a map and the order doesn't matter. Only the interface renderers
would have to go in an ordered list. And in that case it's easier to
provide an ordered List to ST with all your interface renderers
already in it than to duplicate a list implementation in ST with add,
remove, insertAt, etc. methods.
>
> StringTemplate st = new ...
>
> st.SetAttributeRenderer(typeof(MyClass), new MyRenderer());
> st.SetAttributeRenderer(typeof(IMyInterface), new MyIRenderer());
> st.SetAttributeRenderer(typeof(object), new MyDefaultRenderer());
>
> st.ToString();
>
I wouldn't mix the class and interface renderers; already mentioned
the reasons in my last post.
> In this example the MyDefaultRenderer will be called for all
> Attributes that are not of type MyClass and do not implements
> IMyInterface. It look quite intuitive to me. The only difference is
> that the order of Setting Renderer matters.
I think a better way, which you can do right now, is for you to
subclass StringTemplate and override setAttribute to automatically
wrap your objects that implement a specific interface with a class for
which you register a renderer. You can handle or ignore priority
issues and it won't require a change to StringTemplate.
>
> It's only suggestion :-) and any other ideas to solve these
> "problems" are welcome.
>
> Thanks,
>
> Vincent
>
> PS: Accessing source from trunk is possible ? How ?
>
>
>
>
> Jonathan Buhacoff wrote:
>>
>> If it's integrated with the class renderers as I showed in my diff,
>> there's a little extra work to do. On the other hand, most classes
>> only implement handful of interfaces, and since this code doesn't do
>> any string processing it will probably be fast enough.
>>
>> Or, if it's implemented as a separate map of renderers, then it will
>> only slow down processing if the programmer has registered any
>> interface renderers. But that seems a little messy to me, maybe more
>> messy than the speed savings is worth.
>>
>> Finally, the other issue with interface renderers is priority - as
>> proposed now, we have no control over which renderer will be found
>> first, and if a class implements more than one interface with a
>> registered renderer, the output will be non-deterministic. I think
>> that's a bad thing.
>>
>> The way to control that would be to have a complete interface to
>> manage the priority of interface renderers, or to have ST implement
>> something like
>> registerInterfaceAttributeRenderers(List<AttributeRenderer>
>> renderers); so the programmer can specify the order of the
>> renderers.
>>
>> So the loop would change to iterating through the registered
>> interface
>> renderers and checking if the value implements each one (and they
>> would be in priority order).
>>
>> That makes things deterministic again, and would require the use of a
>> list of interface renders separate from the map of class renderers,
>> which means only people who use interface renderers would incur any
>> performance penalty.
>>
>> I'm still trying to think of a case where this scheme would be better
>> than wrapping everything with an adapter and registering a renderer
>> for that, because automatically wrapping certain classes that
>> implement an interface automatically is so easy to do by subclassing
>> StringTemplate. I'm still thinking along the lines of
>> internationalization, units of measure, stuff like that. Vincent
>> can
>> you provide a real world case?
>>
>>
>> On Oct 22, 2009, at 9:45 AM, Sam Harwell wrote:
>>
>>
>>> Hi Vincent,
>>>
>>> My first thought is this changes an O(1) algorithm that has to run
>>> for
>>> every rendered item into an O(n) algorithm. I would have to run this
>>> through the instrumenting profiler to make sure it isn't slowing
>>> down
>>> the rendering process before I could include it. There are a few
>>> other
>>> ways to approach the problem, but I'm not yet sure which one would
>>> work
>>> out best.
>>>
>>> Sam
>>>
>>> -----Original Message-----
>>> From: stringtemplate-interest-bounces at antlr.org
>>> [mailto:stringtemplate-interest-bounces at antlr.org] On Behalf Of
>>> Vincent
>>> DARON
>>> Sent: Thursday, October 22, 2009 10:12 AM
>>> To: stringtemplate-interest at antlr.org
>>> Subject: [stringtemplate-interest] IAttributeRenderer and Type
>>> Inheritancein C#
>>>
>>> Hi
>>>
>>> I would like to be able to register an IAttributeRenderer for
>>> objects
>>> implementing an Interface.
>>>
>>> Part of current implementation of GetAttributeRenderer
>>>
>>> public virtual IAttributeRenderer GetAttributeRenderer( Type
>>> attributeClassType )
>>> {
>>> IAttributeRenderer renderer = null;
>>> if ( _attributeRenderers != null )
>>> {
>>> if ( !_attributeRenderers.TryGetValue(
>>> attributeClassType, out renderer ) )
>>> renderer = null;
>>> }
>>> // ...snip ... //
>>> }
>>>
>>>
>>> My proposal (untested, but should be ok)
>>>
>>> public virtual IAttributeRenderer GetAttributeRenderer( Type
>>> attributeClassType )
>>> {
>>> IAttributeRenderer renderer = null;
>>> if ( _attributeRenderers != null )
>>> {
>>> foreach(Type key in _attributeRenderers.Keys)
>>> {
>>> if(key.IsAssignableFrom(attributeClassType))
>>> {
>>> renderer = _attributeRenderers[key];
>>> break;
>>> }
>>> }
>>> }
>>> // ...snip ... //
>>> }
>>>
>>>
>>> It will allow to register Attribute Renderer for objects
>>> implementing
>>> interfaces
>>>
>>> RegisterAttributeRenderer(typeof(IFormatProvider), ...);
>>>
>>> Goot idea ?
>>>
>>> Second question, is it possible to have access to source using
>>> Source
>>> Control (Subversion, Hg, Git, ...) ? It would be far easier to test
>>> and
>>> create patches.
>>>
>>> Thanks for answer/comments
>>>
>>> Vincent
>>> _______________________________________________
>>> stringtemplate-interest mailing list
>>> stringtemplate-interest at antlr.org
>>> http://www.antlr.org/mailman/listinfo/stringtemplate-interest
>>> _______________________________________________
>>> stringtemplate-interest mailing list
>>> stringtemplate-interest at antlr.org
>>> http://www.antlr.org/mailman/listinfo/stringtemplate-interest
>>>
>>
>> _______________________________________________
>> stringtemplate-interest mailing list
>> stringtemplate-interest at antlr.org
>> http://www.antlr.org/mailman/listinfo/stringtemplate-interest
>>
>>
>
> _______________________________________________
> stringtemplate-interest mailing list
> stringtemplate-interest at antlr.org
> http://www.antlr.org/mailman/listinfo/stringtemplate-interest
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/stringtemplate-interest/attachments/20091022/84a4669e/attachment-0001.html
More information about the stringtemplate-interest
mailing list