List Info

Thread: enhanced foreach loops




enhanced foreach loops
user name
2006-11-16 18:32:26
I would like to enhance the foreach loop by adding next and
previous to 
the foreach variables.

Example usage:

{foreach from=$message.backtrace item='call'
name='backtrace'}
  {assign var='previous_call'
value=|$smarty.foreach.backtrace.next}|
  <li style='list-style: none;'>{$call.file}
[{$call.line}] - 
{$previous_call.class}.{$previous_call.function}(){/if}</
li>
{/foreach}

In case you cannot tell I am using this to print a backtrace
( I want it 
to show the method it is currently in, not the one that it
is calling ).

Where does the foreach implementation reside in source?  And
is this a 
good thing to add to the base code?

-- 
Kerry Wilson
Lead Developer
Williams Web
kwilsonwmsco.com | 423.485.4747


-- 
Smarty Development Mailing List (http://smarty.php.net/)
To unsubscribe, visit: http://www.php.net/unsub
.php
enhanced foreach loops
user name
2006-11-16 18:50:35
Very interesting idea... You could do {assign
var=previous_call 
value=$message.backtrace[$smarty.foreach.backtrace.index +
1]} but it 
wouldn't work for associative arrays or objects.  I like it!
 What would 
be the desired behavior of $smarty.foreach.NAME.next when on
the last 
item?  A default value? NULL?

--Ken

Kerry Wilson wrote:
> I would like to enhance the foreach loop by adding next
and previous 
> to the foreach variables.
>
> Example usage:
>
> {foreach from=$message.backtrace item='call'
name='backtrace'}
>  {assign var='previous_call'
value=|$smarty.foreach.backtrace.next}|
>  <li style='list-style: none;'>{$call.file}
[{$call.line}] - 
>
{$previous_call.class}.{$previous_call.function}(){/if}</
li>
> {/foreach}
>
> In case you cannot tell I am using this to print a
backtrace ( I want 
> it to show the method it is currently in, not the one
that it is 
> calling ).
>
> Where does the foreach implementation reside in source?
 And is this a 
> good thing to add to the base code?
>

-- 
Smarty Development Mailing List (http://smarty.php.net/)
To unsubscribe, visit: http://www.php.net/unsub
.php

enhanced foreach loops
user name
2006-11-16 19:03:22
I have to agree with Ken, its a interesting idea and also a
very useful one
since it will allow to remove some redundant cycles/assigns
to obtain that
value.

On the issue of the value, I guess the logical one would be
NULL (since its
not assigned/existent) or optional, which I don't like but
possible, to
break cycle if one of elements don't exist.


Greets,
Miguel Simões

On 11/16/06, Ken Snyder <ksnydercoremr.com> wrote:
>
> Very interesting idea... You could do {assign
var=previous_call
>
value=$message.backtrace[$smarty.foreach.backtrace.index +
1]} but it
> wouldn't work for associative arrays or objects.  I
like it!  What would
> be the desired behavior of $smarty.foreach.NAME.next
when on the last
> item?  A default value? NULL?
>
> --Ken
>
> Kerry Wilson wrote:
> > I would like to enhance the foreach loop by adding
next and previous
> > to the foreach variables.
> >
> > Example usage:
> >
> > {foreach from=$message.backtrace item='call'
name='backtrace'}
> >  {assign var='previous_call'
value=|$smarty.foreach.backtrace.next}|
> >  <li style='list-style: none;'>{$call.file}
[{$call.line}] -
> >
{$previous_call.class}.{$previous_call.function}(){/if}</
li>
> > {/foreach}
> >
> > In case you cannot tell I am using this to print a
backtrace ( I want
> > it to show the method it is currently in, not the
one that it is
> > calling ).
> >
> > Where does the foreach implementation reside in
source?  And is this a
> > good thing to add to the base code?
> >
>
> --
> Smarty Development Mailing List (http://smarty.php.net/)
> To unsubscribe, visit: http://www.php.net/unsub
.php
>
>
enhanced foreach loops
user name
2006-11-16 19:21:32
False or null is fine with me.  I am working on it and here
is the 
problems I have found.  I am trying to use the prev and next
functions, 
these move the internal pointer on the array.  They behave
differently 
whether the array in the foreach is a reference or not:

$array = array( 'a' => 'a', 'b' => 'b', 'c' => 'c'
);
$_from = $array;
foreach( $_from AS $key => $value ) {
  $element = current($_from);
  echo $element;
}

will print aaa, since the internal cursor of _from will not
be moved and 
a will be the current one

where as:
$_from = &$array;

will print abc, b/c the internal cursor is moved

so for next and previous methods to work with smarty the
_from 
assignment will have to be changed to reference ( & )
and we have to be 
careful not to move pointer ( php doesn't have method for
'peeking' ahead? )

prev($_from); // Rewind b/c current is really the next
element
$previous = prev($_from); // This assigns previous
next($_from); // Now we are back to previous
next($_from); // Now we are back to current
$next = next($_from);  // Get next
prev($_from); // move back to current

wow all that just to get the neighboring values, anyone know
a better way?


Ken Snyder wrote:
> Very interesting idea... You could do {assign
var=previous_call 
>
value=$message.backtrace[$smarty.foreach.backtrace.index +
1]} but it 
> wouldn't work for associative arrays or objects.  I
like it!  What 
> would be the desired behavior of
$smarty.foreach.NAME.next when on the 
> last item?  A default value? NULL?
>
> --Ken
>
> Kerry Wilson wrote:
>> I would like to enhance the foreach loop by adding
next and previous 
>> to the foreach variables.
>>
>> Example usage:
>>
>> {foreach from=$message.backtrace item='call'
name='backtrace'}
>>  {assign var='previous_call'
value=|$smarty.foreach.backtrace.next}|
>>  <li style='list-style: none;'>{$call.file}
[{$call.line}] - 
>>
{$previous_call.class}.{$previous_call.function}(){/if}</
li>
>> {/foreach}
>>
>> In case you cannot tell I am using this to print a
backtrace ( I want 
>> it to show the method it is currently in, not the
one that it is 
>> calling ).
>>
>> Where does the foreach implementation reside in
source?  And is this 
>> a good thing to add to the base code?
>>
>


-- 
Kerry Wilson
Lead Developer
Williams Web
kwilsonwmsco.com | 423.485.4747


-- 
Smarty Development Mailing List (http://smarty.php.net/)
To unsubscribe, visit: http://www.php.net/unsub
.php
enhanced foreach loops
user name
2006-11-16 20:28:33
Hi.

Kerry Wilson <kwilsonwmsco.com> wrote: False
or null is fine with me.  I am working on it and here is the

problems I have found.  I am trying to use the prev and next
functions, 
these move the internal pointer on the array.  They behave
differently 
whether the array in the foreach is a reference or not:

$array = array( 'a' => 'a', 'b' => 'b', 'c' => 'c'
);
$_from = $array;
foreach( $_from AS $key => $value ) {
  $element = current($_from);
  echo $element;
}

will print aaa, since the internal cursor of _from will not
be moved and 
a will be the current one

where as:
$_from = &$array;

will print abc, b/c the internal cursor is moved

so for next and previous methods to work with smarty the
_from 
assignment will have to be changed to reference ( & )
and we have to be 
careful not to move pointer ( php doesn't have method for
'peeking' ahead? )

prev($_from); // Rewind b/c current is really the next
element
$previous = prev($_from); // This assigns previous
next($_from); // Now we are back to previous
next($_from); // Now we are back to current
$next = next($_from);  // Get next
prev($_from); // move back to current

wow all that just to get the neighboring values, anyone know
a better way?

I haven't looked at it in a long time, but I seem to recall
that the last I did check, getting neighboring items in an
associative array is not possible without moving the pointer
-- and that is not desirable. I'm also weary of the extra
code generation (and hence, execution) that this involves.
Finally, does it consider moving past the end of the loop?
Does it support Traversable in PHP5 (or at least iterators)?
Probably yes on both -- just checking.

As for previous, since you will be moving through the array
anyways, it may be better to just track previous internally
(perhaps with a reference) rather than rely on prev(). That
should result in less pointer movement; never-the-less, I
have reservations.

Ken Snyder wrote:
> Very interesting idea... You could do {assign
var=previous_call 
>
value=$message.backtrace[$smarty.foreach.backtrace.index +
1]} but

No you couldn't. That syntax is not supported in Smarty.
Besides, we already have iteration which is index+1 anyhow
for foreach. 

 it 
> wouldn't work for associative arrays or objects.  I
like it!  What 
> would be the desired behavior of
$smarty.foreach.NAME.next when on the 
> last item?  A default value? NULL?
>
> --Ken
>
> Kerry Wilson wrote:
>> I would like to enhance the foreach loop by adding
next and previous 
>> to the foreach variables.
>>
>> Example usage:
>>
>> {foreach from=$message.backtrace item='call'
name='backtrace'}
>>  {assign var='previous_call'
value=|$smarty.foreach.backtrace.next}|
>>  
{$call.file} [{$call.line}] - 
>>
{$previous_call.class}.{$previous_call.function}(){/if}
>> {/foreach}
>>
>> In case you cannot tell I am using this to print a
backtrace ( I want 
>> it to show the method it is currently in, not the
one that it is 
>> calling ).
>>
>> Where does the foreach implementation reside in
source?  And is this 
>> a good thing to add to the base code?

It is in the Smarty_Compiler.class.php file (see:
_compile_tag() and _compile_foreach_start(). Is it a good
thing to add? Considering the edge cases (references,
objects) and the performance impacts on the general case
(ie: no need for prev/next), my gut tells me no -- at least
not in the Smarty 2.x (PHP4) design. Personally, I'd rather
keep  very simple and without much magic (and hence
as fast as possible for the typical cases) and have users
implement their own looping constructs using block plugins
when they need special functionality. BTW: note that for
similar reasons, we don't support, start, max or skip on
foreach.

Of course, if you come up with a non-intrusive, fail-safe
way of doing it, then that is another thing.

boots

-- 
Kerry Wilson
Lead Developer
Williams Web
kwilsonwmsco.com | 423.485.4747

 
---------------------------------
Sponsored Link

   Degrees for working adults in as fast as 1 year.
Bachelors, Masters, Associates. Top schools
enhanced foreach loops
user name
2006-11-16 20:42:55
Kerry Wilson wrote:
> I would like to enhance the foreach loop by adding next
and previous 
> to the foreach variables.
>
> Example usage:
>
> {foreach from=$message.backtrace item='call'
name='backtrace'}
>  {assign var='previous_call'
value=|$smarty.foreach.backtrace.next}|
>  <li style='list-style: none;'>{$call.file}
[{$call.line}] - 
>
{$previous_call.class}.{$previous_call.function}(){/if}</
li>
> {/foreach}
>
> In case you cannot tell I am using this to print a
backtrace ( I want 
> it to show the method it is currently in, not the one
that it is 
> calling ).
>
> Where does the foreach implementation reside in source?
 And is this a 
> good thing to add to the base code?
>

Here is the code for the feature enhancement, it goes in 
Smarty_Compiler.class.php around line 1185.

$output .= "if ({$foreach_props}['total'] >
0):n";
$output .= "    $_values =
array_values($_from);n";
$output .= "    foreach ($_from as 
$key_part$this->_tpl_vars['$item']):n";
$output .= "        if( isset( 
$_values[{$foreach_props}['iteration']-1] ) ) { 
{$foreach_props}['prev'] =
$_values[{$foreach_props}['iteration']-1]; } 
else { {$foreach_props}['prev'] = false; }n";
$output .= "        if( isset( 
$_values[{$foreach_props}['iteration']+1] ) ) { 
{$foreach_props}['next'] =
$_values[{$foreach_props}['iteration']+1]; } 
else { {$foreach_props}['next'] = false; }n";
$output .= "       
{$foreach_props}['iteration']++;n";

It actually turned out to be cleaner than I expected.  It
would be great 
if this were added to the next release so my code doesn't
break when I 
upgrade!

kw

-- 
Kerry Wilson
Lead Developer
Williams Web
kwilsonwmsco.com | 423.485.4747


-- 
Smarty Development Mailing List (http://smarty.php.net/)
To unsubscribe, visit: http://www.php.net/unsub
.php
enhanced foreach loops
user name
2006-11-16 21:09:03
Kerry Wilson <kwilsonwmsco.com> wrote: Kerry
Wilson wrote:
> I would like to enhance the foreach loop by adding next
and previous 
> to the foreach variables.
>
> Example usage:
>
> {foreach from=$message.backtrace item='call'
name='backtrace'}
>  {assign var='previous_call'
value=|$smarty.foreach.backtrace.next}|
>  
{$call.file} [{$call.line}] - 
> {$previous_call.class}.{$previous_call.function}(){/if}
> {/foreach}
>
> In case you cannot tell I am using this to print a
backtrace ( I want 
> it to show the method it is currently in, not the one
that it is 
> calling ).
>
> Where does the foreach implementation reside in source?
 And is this a 
> good thing to add to the base code?
>

Here is the code for the feature enhancement, it goes in 
Smarty_Compiler.class.php around line 1185.

$output .= "if ({$foreach_props}['total'] >
0):n";
$output .= "    $_values =
array_values($_from);n";
$output .= "    foreach ($_from as 
$key_part$this->_tpl_vars['$item']):n";
$output .= "        if( isset( 
$_values[{$foreach_props}['iteration']-1] ) ) { 
{$foreach_props}['prev'] =
$_values[{$foreach_props}['iteration']-1]; } 
else { {$foreach_props}['prev'] = false; }n";
$output .= "        if( isset( 
$_values[{$foreach_props}['iteration']+1] ) ) { 
{$foreach_props}['next'] =
$_values[{$foreach_props}['iteration']+1]; } 
else { {$foreach_props}['next'] = false; }n";
$output .= "       
{$foreach_props}['iteration']++;n";

It actually turned out to be cleaner than I expected.  It
would be great 
if this were added to the next release so my code doesn't
break when I 
upgrade!

kw
Unfortunately, array_values() has memory implications and
possibly severe performance implications for PHP5 iterator
implementing objects; otherwise a nice solution, but I still
think you should implement as a plugin. Maybe consider a
compiler plugin for this one.

boots
 
---------------------------------
Sponsored Link

Mortgage rates near 39yr lows. $510,000 Mortgage for
$1,698/mo -   Calculate new house payment
enhanced foreach loops
user name
2006-11-17 09:05:57
Kerry Wilson wrote:
> False or null is fine with me.  I am working on it and
here is the 
> problems I have found.  I am trying to use the prev and
next functions, 
> these move the internal pointer on the array.  They
behave differently 
> whether the array in the foreach is a reference or not:
> 
> $array = array( 'a' => 'a', 'b' => 'b', 'c' =>
'c' );
> $_from = $array;
> foreach( $_from AS $key => $value ) {
>  $element = current($_from);
>  echo $element;
> }
> 
> will print aaa, since the internal cursor of _from will
not be moved and 
> a will be the current one
> 
> where as:
> $_from = &$array;
> 
> will print abc, b/c the internal cursor is moved
no, it does not, it prints out "bc " as in the
loop current() is already 
the next one.

I really wonder what such "enhancement" can serve.
-- 
toggg
> 
> so for next and previous methods to work with smarty
the _from 
> assignment will have to be changed to reference ( &
) and we have to be 
> careful not to move pointer ( php doesn't have method
for 'peeking' 
> ahead? )
> 
> prev($_from); // Rewind b/c current is really the next
element
> $previous = prev($_from); // This assigns previous
> next($_from); // Now we are back to previous
> next($_from); // Now we are back to current
> $next = next($_from);  // Get next
> prev($_from); // move back to current
> 
> wow all that just to get the neighboring values, anyone
know a better way?
> 
> 
> Ken Snyder wrote:
>> Very interesting idea... You could do {assign
var=previous_call 
>>
value=$message.backtrace[$smarty.foreach.backtrace.index +
1]} but it 
>> wouldn't work for associative arrays or objects.  I
like it!  What 
>> would be the desired behavior of
$smarty.foreach.NAME.next when on the 
>> last item?  A default value? NULL?
>>
>> --Ken
>>
>> Kerry Wilson wrote:
>>> I would like to enhance the foreach loop by
adding next and previous 
>>> to the foreach variables.
>>>
>>> Example usage:
>>>
>>> {foreach from=$message.backtrace item='call'
name='backtrace'}
>>>  {assign var='previous_call'
value=|$smarty.foreach.backtrace.next}|
>>>  <li style='list-style:
none;'>{$call.file} [{$call.line}] - 
>>>
{$previous_call.class}.{$previous_call.function}(){/if}</
li>
>>> {/foreach}
>>>
>>> In case you cannot tell I am using this to
print a backtrace ( I want 
>>> it to show the method it is currently in, not
the one that it is 
>>> calling ).
>>>
>>> Where does the foreach implementation reside in
source?  And is this 
>>> a good thing to add to the base code?
>>>
>>
> 
> 

-- 
Smarty Development Mailing List (http://smarty.php.net/)
To unsubscribe, visit: http://www.php.net/unsub
.php

[1-8]

about | contact  Other archives ( Real Estate discussion Medical topics )