Re: map?get(nonStringKey) for FM 2.3.x?

Daniel Dekany <[email protected]>
Newsgroups gmane.comp.web.freemarker.devel
Message-ID <[email protected]>
Friday, August 10, 2012, 2:54:29 PM, Denis Bredelet wrote:

> Hi Daniel,
>
>> FTL has this annoying problem that it has no type that corresponds to
>> Java's Map. It has a type called hash, but it was introduced for
>> variable hierarchies (like `user.name`), so the keys are limited to
>> stings. For some reason TemplateMapModel wasn't introduced, instead,
>> the bundled wrappers wrap Map-s as hashes, which of course doesn't
>> work for non-string keys. Except, if you call the Map.get method
>> directly from the template, but since FTL doesn't use separate
>> name-spaces for plain sub-variables and methods, if Map methods are
>> exposed, they mix with the actual string keys, which is a mess, so by
>> default Map methods are hidden. Luckily, with BeansWrapper, you can
>> just do `someMap(nonStringKey)`, but sadly, BeansWrapper is not used
>> by default for wrapping Map-s, they are wrapped into a SimpleHash
>> instead.
>
> What is wrong with Beans Wrapper approach?

One problem is that the default object wrapper doesn't use it for
wrapping maps, so I can't just tell users (in the FAQ for example) to
write `map(key)` instead of `map[key]`.

Another problem is that if the users sees `foo(bar)` in a template, he
will not think that `foo` is a map, and that you have just get a value
from it. I won't either. It doesn't look like that. (Plus, most Java
programmers didn't even heard about first-class functions, which makes
this even stranger for them.)

>> So the user asks how to get an item from this map with a non-String
>> key, and we don't have a simple answer. You need to use BeansWrapper
>> instead of the default... oh, but wait, switching wrapper might breaks
>> your application, and depending on the framework there's possibly no
>> way to set the object wrapper at all. How to fix this situation:
>> 
>> - Ultimately, add TemplateMapModel, and a new recommended
>>  ObjectWrapper that uses it too. Unfortunately, this is not an option
>>  for existing applications and frameworks, unless they willing to
>>  review their templates.
>> 
>> - SimpleHash should implement TemplateMethodModelEx, so
>>  `someMap(nonStringKey)` works for SimpleHash-wrapped templates too.
>>  My problem with this is that calling a map like a method is quite
>>  confusing for most programmers. You look at the template, and
>>  believe that "someMap" is primarily a function. But it's a Map.
>>  Also adding TemplateMethodModelEx to SimpleHash can break existing
>>  applications with a small chance.
>
> I want to see a concrete demonstration of the problems with this
> solution. Personally I think it would work well.
>
> How is it confusing?

See earlier. Compare it with `foo?get(bar)`. In the second case it's
easier to see what's going on. It's almost `foo.get(bar)` after all.

> What does it break?

Previously the wrapped map didn't implement TemplateMethodModelEx. So
if something checks that before checking for TemplateHashModel, the
code will go on a different path.

> Thanks,
> -- Denis.
>
>> 
>> - Add `get` as built-in, which will utilize its knowledge of the
>>  bundled wrappers to get to the Map behind. No mater how "someMap"
>>  was wrapped, if there's a Map behind, `someMap?get(key)` just works.
>>  If the wrapper is not recognized, nor AdapterTemplateModel is
>>  implemented, it can still call TemplateHashModel.get(String) and give
>>  an error for a non-String key.
>> 
>> -- 
>> Best regards,
>> Daniel Dekany

-- 
Best regards,
 Daniel Dekany


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.