Testing for nulls with #if

View: New views
7 Messages — Rating Filter:   Alert me  

Testing for nulls with #if

by Margus Kliimask-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,
I've run into a problem with testing for a null in #defined block with
an #if directive. The manual states: "The variable $foo is evaluated
to determine whether it is true, which will happen under one of two
circumstances: <..> or (ii) the value is not null.

I feed an array of lists
...
String[] [] Items = {{"A", "100"}, {"B", null}};
context.put("Items", Items);
...

to this Velocity script:
...
#define( $key )$item.get(0)#end
#define( $val )$item.get(1)#end

#foreach ( $item in $Items )
(1)#if( $item.get(1) )$key:$val
#end
(2)#if( $val )$key:$val
#end

#end
...

I get back:
(1)A:100
(2)A:100

(1)(2)B:$item.get(1)

So, #if could detect null (missing value) in #if( $item.get(1) ), but
could not in #defined block #if( $val ). What am I missing? I
definitely don't want to mention the b-word here :) and appreciate any
help, guidance or comments.

Thanks,
Margus

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@...
For additional commands, e-mail: user-help@...


Re: Testing for nulls with #if

by Nathan Bubna :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

When the innards of the $val block ($item.get(1)) resolve to null,
they are output as they were.  So $val should render as the literal
string "$item.get(1)".  That string is definitely not null.   If you
want, you can use quiet notation ($!item.get(1)), but even that will
render as an empty string "", which is also not null.  So, no matter
what, your $val reference will not be null.  It is a defined block
object which never renders as null.  It is not a workable shortcut for
null testing.  You can do #if( $val == "" ) if you switch to quiet
notation or #if( $val == "$item.get(1)" ) to test properly as things
are.

On Wed, Oct 14, 2009 at 3:35 AM, Margus Kliimask
<margus.kliimask@...> wrote:

> Hi,
> I've run into a problem with testing for a null in #defined block with
> an #if directive. The manual states: "The variable $foo is evaluated
> to determine whether it is true, which will happen under one of two
> circumstances: <..> or (ii) the value is not null.
>
> I feed an array of lists
> ...
> String[] [] Items = {{"A", "100"}, {"B", null}};
> context.put("Items", Items);
> ...
>
> to this Velocity script:
> ...
> #define( $key )$item.get(0)#end
> #define( $val )$item.get(1)#end
>
> #foreach ( $item in $Items )
> (1)#if( $item.get(1) )$key:$val
> #end
> (2)#if( $val )$key:$val
> #end
>
> #end
> ...
>
> I get back:
> (1)A:100
> (2)A:100
>
> (1)(2)B:$item.get(1)
>
> So, #if could detect null (missing value) in #if( $item.get(1) ), but
> could not in #defined block #if( $val ). What am I missing? I
> definitely don't want to mention the b-word here :) and appreciate any
> help, guidance or comments.
>
> Thanks,
> Margus
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@...
> For additional commands, e-mail: user-help@...
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@...
For additional commands, e-mail: user-help@...


Inhrited public methods not visible to Velocity

by Steve O'Hara :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I have a class that extends an abstract class which is placed into a
Velocity context.  However, the public methods of the abstract class are
not visible to Velocity.

I looked at the source code and can see that getDeclaredMethods() is
being used rather than getMethods()

Is there a reason for that?

Thanks,
Steve


---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@...
For additional commands, e-mail: user-help@...


Re: Inhrited public methods not visible to Velocity

by Nathan Bubna :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Oct 14, 2009 at 8:44 AM, Steve O'Hara
<sohara@...> wrote:
> I have a class that extends an abstract class which is placed into a
> Velocity context.  However, the public methods of the abstract class are
> not visible to Velocity.

is the abstract class public?  VelocityTools itself does this successfully.

> I looked at the source code and can see that getDeclaredMethods() is
> being used rather than getMethods()
>
> Is there a reason for that?

Yes, the intention is to support public methods declared in public
classes.  So we navigate the class heirarchy looking for those.

It's also always helpful with such questions to mention the version of
Velocity being used.

>
> Thanks,
> Steve
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@...
> For additional commands, e-mail: user-help@...
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@...
For additional commands, e-mail: user-help@...


RE: Inhrited public methods not visible to Velocity

by Steve O'Hara :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Nathan,

Thanks for your reply - I'm using v6.2
Yes, the abstract class is public and the methods in the abstract class are also public.

I've taken another look at ClassMap.java and can see how you're recursing up the super classes to get all the public methods.  Forgive my naivety, but why is this necessary?  Wouldn't a simple call to getMethods() do this for you which would also save having to check if the method is public?  

I'll see if I can debug why the introspector is not working in my case and come back to the list.

Steve


-----Original Message-----
From: user-return-20992-sohara=pivotal-solutions.co.uk@... [mailto:user-return-20992-sohara=pivotal-solutions.co.uk@...] On Behalf Of Nathan Bubna
Sent: 14 October 2009 20:38
To: Velocity Users List
Subject: Re: Inhrited public methods not visible to Velocity

On Wed, Oct 14, 2009 at 8:44 AM, Steve O'Hara
<sohara@...> wrote:
> I have a class that extends an abstract class which is placed into a
> Velocity context.  However, the public methods of the abstract class are
> not visible to Velocity.

is the abstract class public?  VelocityTools itself does this successfully.

> I looked at the source code and can see that getDeclaredMethods() is
> being used rather than getMethods()
>
> Is there a reason for that?

Yes, the intention is to support public methods declared in public
classes.  So we navigate the class heirarchy looking for those.

It's also always helpful with such questions to mention the version of
Velocity being used.

>
> Thanks,
> Steve
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@...
> For additional commands, e-mail: user-help@...
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@...
For additional commands, e-mail: user-help@...



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@...
For additional commands, e-mail: user-help@...


RE: Inhrited public methods not visible to Velocity

by Steve O'Hara :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Of course, it turned out to be an error on my part.... sorry about that

However as an aside, I changed the velocity code to call getMethods and removed the recursion in ClassMap.java and that worked fine.  I know it's only a small thing and it's not exactly a fix because the code isn't broken, but maybe it's worth making the change for the small amount of possible performance gain.  I'll leave it up to you.

Cheers,
Steve


-----Original Message-----
From: Steve O'Hara
Sent: 15 October 2009 09:22
To: Velocity Users List
Subject: RE: Inhrited public methods not visible to Velocity

Hi Nathan,

Thanks for your reply - I'm using v6.2
Yes, the abstract class is public and the methods in the abstract class are also public.

I've taken another look at ClassMap.java and can see how you're recursing up the super classes to get all the public methods.  Forgive my naivety, but why is this necessary?  Wouldn't a simple call to getMethods() do this for you which would also save having to check if the method is public?  

I'll see if I can debug why the introspector is not working in my case and come back to the list.

Steve


-----Original Message-----
From: user-return-20992-sohara=pivotal-solutions.co.uk@... [mailto:user-return-20992-sohara=pivotal-solutions.co.uk@...] On Behalf Of Nathan Bubna
Sent: 14 October 2009 20:38
To: Velocity Users List
Subject: Re: Inhrited public methods not visible to Velocity

On Wed, Oct 14, 2009 at 8:44 AM, Steve O'Hara
<sohara@...> wrote:
> I have a class that extends an abstract class which is placed into a
> Velocity context.  However, the public methods of the abstract class are
> not visible to Velocity.

is the abstract class public?  VelocityTools itself does this successfully.

> I looked at the source code and can see that getDeclaredMethods() is
> being used rather than getMethods()
>
> Is there a reason for that?

Yes, the intention is to support public methods declared in public
classes.  So we navigate the class heirarchy looking for those.

It's also always helpful with such questions to mention the version of
Velocity being used.

>
> Thanks,
> Steve
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@...
> For additional commands, e-mail: user-help@...
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@...
For additional commands, e-mail: user-help@...



---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@...
For additional commands, e-mail: user-help@...


Re: Inhrited public methods not visible to Velocity

by Nathan Bubna :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Oct 15, 2009 at 2:34 AM, Steve O'Hara
<sohara@...> wrote:
> Of course, it turned out to be an error on my part.... sorry about that
>
> However as an aside, I changed the velocity code to call getMethods and
> removed the recursion in ClassMap.java and that worked fine.  I know it's
> only a small thing and it's not exactly a fix because the code isn't broken,
> but maybe it's worth making the change for the small amount of possible
> performance gain.  I'll leave it up to you.

Did all tests pass too?

Historical reasons are all i can think of right now.  It is how it was
done.  I think, too, it was a way to keep out public methods inherited
from protected classes.  I kinda doubt the current dev community
(myself included) would care about that anymore.

I'm not sure whether there's much performance gain to be had by the
swap, but certainly it seems like it would simplify the code and
perhaps obviate such strange bugs as VELOCITY-736.

If you would be so kind as to open a JIRA issue on this, i think it is
something we should consider.

> Cheers,
> Steve
>
>
> -----Original Message-----
> From: Steve O'Hara
> Sent: 15 October 2009 09:22
> To: Velocity Users List
> Subject: RE: Inhrited public methods not visible to Velocity
>
> Hi Nathan,
>
> Thanks for your reply - I'm using v6.2
> Yes, the abstract class is public and the methods in the abstract class are also public.
>
> I've taken another look at ClassMap.java and can see how you're recursing up the super classes to get all the public methods.  Forgive my naivety, but why is this necessary?  Wouldn't a simple call to getMethods() do this for you which would also save having to check if the method is public?
>
> I'll see if I can debug why the introspector is not working in my case and come back to the list.
>
> Steve
>
>
> -----Original Message-----
> From: user-return-20992-sohara=pivotal-solutions.co.uk@... [mailto:user-return-20992-sohara=pivotal-solutions.co.uk@...] On Behalf Of Nathan Bubna
> Sent: 14 October 2009 20:38
> To: Velocity Users List
> Subject: Re: Inhrited public methods not visible to Velocity
>
> On Wed, Oct 14, 2009 at 8:44 AM, Steve O'Hara
> <sohara@...> wrote:
>> I have a class that extends an abstract class which is placed into a
>> Velocity context.  However, the public methods of the abstract class are
>> not visible to Velocity.
>
> is the abstract class public?  VelocityTools itself does this successfully.
>
>> I looked at the source code and can see that getDeclaredMethods() is
>> being used rather than getMethods()
>>
>> Is there a reason for that?
>
> Yes, the intention is to support public methods declared in public
> classes.  So we navigate the class heirarchy looking for those.
>
> It's also always helpful with such questions to mention the version of
> Velocity being used.
>
>>
>> Thanks,
>> Steve
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: user-unsubscribe@...
>> For additional commands, e-mail: user-help@...
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@...
> For additional commands, e-mail: user-help@...
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@...
> For additional commands, e-mail: user-help@...
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscribe@...
For additional commands, e-mail: user-help@...