Thread: [Webtek-devel] bug in foreach
Status: Alpha
Brought to you by:
prozessor13
From: Adrian S. <adr...@gm...> - 2008-06-15 11:56:08
|
I just searched for ages for this bug! <% foreach list="...." iterator="xyz" do~q{ <% a_macro param="<% xyz %>" %> } %> This doesn't work, producing the error: macro_error : MyApp::Page::MyPage=HASH(0x227f904) has no macro 'xyz' If I implement the following method in class Xyz: sub self :Macro { my $self = shift; return $self; } and then put the following in the template: <% foreach list="...." iterator="xyz" do~q{ <% a_macro param="<% xyz.self %>" %> } %> Then it works fine |
From: max d. <pro...@gm...> - 2008-06-16 07:53:31
|
hmmm.. this is no bug, because you used the macro in a wrong way. the format of a macro is defined like: <% handler.handler.macro_name param1="abc" param2=" ... <% ... %> ..." | filter1 | filter2 param="..." %> if you omit the handler (i.e. you want to call a macro in the current page) you can write: <% macro_name param1="abc" param2=" ... <% ... %> ..." | filter1 | filter2 param="..." %> for better understanding you can think the above macro-call is the same as: <% actual_page.macro_name ... %> (but the handler actual_page dont exists, because it's already the default) so to your example: i think you want to put the current iterator (which is a handler obj) as a param to a macro, like: sub a_macro { my ($self, %params) = @_; return $params{'iterator_obj'}->some_macro(); } but this is not possible because, when you write: <% a_macro iterator_obj="<% xyz %>" %> xyz is called as a macro function for the current page (and this is exactly the error-msg from your example) so, there are two solutions for this problem. 1) our solution with the self macro have done the trick (because it returns the handler obj) 2) handler xyz is already defined for the current page (from the foreach macro), so you can write in the macro-code: sub a_macro { my ($self, %params) = @_; return $self->handler($params{'handler_name'})->some_macro(); } and in the template <% foreach iterator="xyz" do~q{ <% a_macro handler_name="xyz" %> } %> hmmm... i think the second solution is not as nice as the first, because you have to split the logic: half in the template (the handler- name) and half in macro-code (handler-obj for the handler-name).. and this solution also only works in the same page, where the foreach is called. so a <% foreach iterator="xyz" do~q{ <% parent.a_macro handler_name="xyz" %> } %> wouldn't work! so i think we should implement a general macro which returns the obj of the current handler (like your self macro). what would you think is the right name for such an macro? is sub self :Macro { ... } a good name? i think its ok, so we should implement this in WebTek/Handler.pm lg. max. On 15.06.2008, at 13:49, Adrian Smith wrote: > I just searched for ages for this bug! > > <% foreach list="...." iterator="xyz" do~q{ > <% a_macro param="<% xyz %>" %> > } %> > > This doesn't work, producing the error: > > macro_error : MyApp::Page::MyPage=HASH(0x227f904) has no macro 'xyz' > > If I implement the following method in class Xyz: > > sub self :Macro { > my $self = shift; > return $self; > } > > and then put the following in the template: > > <% foreach list="...." iterator="xyz" do~q{ > <% a_macro param="<% xyz.self %>" %> > } %> > > Then it works fine |
From: Adrian S. <adr...@gm...> - 2008-06-26 15:50:35
|
OK - Thanks for the description. I am not sure I agree/understand the difference between a Handler and a Macro. I mean they could just be the same? Sometimes a Macro returns a non-string (e.g. as the input for the "list" paramter of "foreach") so given that Macros return "anything" - strings, lists, objects - it would make sense for attributes of them (with the "." syntax) to be usable. I mean in programming languages, you can write: - $box - $box->get_dimensions() - $box->get_dimensions()->get_width() There is no distinction where the first doesn't work at all, the second only works if get_dimensions is a Macro, and the third only works if get_dimensions is a Handler. But anyway - now I understand the difference (I think) - so it doesn't matter too much on a practical level for me. 2008/6/16 max demmelbauer <pro...@gm...>: > hmmm.. this is no bug, because you used the macro in a wrong way. > > the format of a macro is defined like: > > <% handler.handler.macro_name param1="abc" param2=" ... <% ... %> ..." | > filter1 | filter2 param="..." %> > > if you omit the handler (i.e. you want to call a macro in the current page) > you can write: > > <% macro_name param1="abc" param2=" ... <% ... %> ..." | filter1 | filter2 > param="..." %> > > for better understanding you can think the above macro-call is the same as: > > <% actual_page.macro_name ... %> > > (but the handler actual_page dont exists, because it's already the default) > > > so to your example: > > i think you want to put the current iterator (which is a handler obj) as a > param to a macro, like: > > sub a_macro { > my ($self, %params) = @_; > > return $params{'iterator_obj'}->some_macro(); > } > > but this is not possible because, when you write: > > <% a_macro iterator_obj="<% xyz %>" %> > > xyz is called as a macro function for the current page (and this is exactly > the error-msg from your example) > > so, there are two solutions for this problem. > > 1) our solution with the self macro have done the trick (because it returns > the handler obj) > > 2) handler xyz is already defined for the current page (from the foreach > macro), so you can write in the macro-code: > > sub a_macro { > my ($self, %params) = @_; > > return $self->handler($params{'handler_name'})->some_macro(); > } > > and in the template > > <% foreach iterator="xyz" do~q{ > <% a_macro handler_name="xyz" %> > } %> > > hmmm... i think the second solution is not as nice as the first, because > you have to split the logic: half in the template (the handler-name) and > half in macro-code (handler-obj for the handler-name).. and this solution > also only works in the same page, where the foreach is called. so a > > <% foreach iterator="xyz" do~q{ > <% parent.a_macro handler_name="xyz" %> > } %> > > wouldn't work! > > so i think we should implement a general macro which returns the obj of the > current handler (like your self macro). what would you think is the right > name for such an macro? > > is > > sub self :Macro { ... } a good name? > > i think its ok, so we should implement this in WebTek/Handler.pm > > lg. max. > > > On 15.06.2008, at 13:49, Adrian Smith wrote: > > I just searched for ages for this bug! > > <% foreach list="...." iterator="xyz" do~q{ > <% a_macro param="<% xyz %>" %> > } %> > > This doesn't work, producing the error: > > macro_error : MyApp::Page::MyPage=HASH(0x227f904) has no macro 'xyz' > > If I implement the following method in class Xyz: > > sub self :Macro { > my $self = shift; > return $self; > } > > and then put the following in the template: > > <% foreach list="...." iterator="xyz" do~q{ > <% a_macro param="<% xyz.self %>" %> > } %> > > Then it works fine > > > |
From: max d. <pro...@gm...> - 2008-06-26 16:18:34
|
the Macro | Handler params are needed * to check the template-syntax during template-compile-time * to dont allow access to every variable within templates (i.e. you let the user modify templates) * to generate documentation if you dont want that check, you can set the failmode="silent" property: <% box.get_dimensions.get_value failmode="silent" %> in case of an runtime-error (during rendering the template) an empty- string is returned for this macro. ...hmmm... but this behavour is still a work in progress. On 26.06.2008, at 17:50, Adrian Smith wrote: > OK - Thanks for the description. > > I am not sure I agree/understand the difference between a Handler > and a Macro. I mean they could just be the same? > > Sometimes a Macro returns a non-string (e.g. as the input for the > "list" paramter of "foreach") so given that Macros return "anything" > - strings, lists, objects - it would make sense for attributes of > them (with the "." syntax) to be usable. > > I mean in programming languages, you can write: > $box > $box->get_dimensions() > $box->get_dimensions()->get_width() > There is no distinction where the first doesn't work at all, the > second only works if get_dimensions is a Macro, and the third only > works if get_dimensions is a Handler. > > But anyway - now I understand the difference (I think) - so it > doesn't matter too much on a practical level for me. > > > > 2008/6/16 max demmelbauer <pro...@gm...>: > hmmm.. this is no bug, because you used the macro in a wrong way. > > the format of a macro is defined like: > > <% handler.handler.macro_name param1="abc" param2=" ... <% ... > %> ..." | filter1 | filter2 param="..." %> > > if you omit the handler (i.e. you want to call a macro in the > current page) you can write: > > <% macro_name param1="abc" param2=" ... <% ... %> ..." | filter1 | > filter2 param="..." %> > > for better understanding you can think the above macro-call is the > same as: > > <% actual_page.macro_name ... %> > > (but the handler actual_page dont exists, because it's already the > default) > > > so to your example: > > i think you want to put the current iterator (which is a handler > obj) as a param to a macro, like: > > sub a_macro { > my ($self, %params) = @_; > > return $params{'iterator_obj'}->some_macro(); > } > > but this is not possible because, when you write: > > <% a_macro iterator_obj="<% xyz %>" %> > > xyz is called as a macro function for the current page (and this is > exactly the error-msg from your example) > > so, there are two solutions for this problem. > > 1) our solution with the self macro have done the trick (because it > returns the handler obj) > > 2) handler xyz is already defined for the current page (from the > foreach macro), so you can write in the macro-code: > > sub a_macro { > my ($self, %params) = @_; > > return $self->handler($params{'handler_name'})->some_macro(); > } > > and in the template > > <% foreach iterator="xyz" do~q{ > <% a_macro handler_name="xyz" %> > } %> > > hmmm... i think the second solution is not as nice as the first, > because you have to split the logic: half in the template (the > handler-name) and half in macro-code (handler-obj for the handler- > name).. and this solution also only works in the same page, where > the foreach is called. so a > > <% foreach iterator="xyz" do~q{ > <% parent.a_macro handler_name="xyz" %> > } %> > > wouldn't work! > > so i think we should implement a general macro which returns the obj > of the current handler (like your self macro). what would you think > is the right name for such an macro? > > is > > sub self :Macro { ... } a good name? > > i think its ok, so we should implement this in WebTek/Handler.pm > > lg. max. > > > On 15.06.2008, at 13:49, Adrian Smith wrote: > >> I just searched for ages for this bug! >> >> <% foreach list="...." iterator="xyz" do~q{ >> <% a_macro param="<% xyz %>" %> >> } %> >> >> This doesn't work, producing the error: >> >> macro_error : MyApp::Page::MyPage=HASH(0x227f904) has no macro 'xyz' >> >> If I implement the following method in class Xyz: >> >> sub self :Macro { >> my $self = shift; >> return $self; >> } >> >> and then put the following in the template: >> >> <% foreach list="...." iterator="xyz" do~q{ >> <% a_macro param="<% xyz.self %>" %> >> } %> >> >> Then it works fine > > |
From: Adrian S. <adr...@gm...> - 2008-06-26 16:32:57
|
OK - I agree (I think) that there needs to be some attribute so that not every method is reachable from the front-end - but I am just not sure that the differentiation between "Macro" and "Handler" is necessary. On the other hand I think most Java web frameworks allow you to put any attribute on the front-end as long as it has the JavaBeans "getXx" notation. And WebObjects also didn't have any special syntax to state that an attribute is accessible from the front-end. But still - I like it - I think it means the class has a much smaller "interface" from the front-end perspective. And small interfaces are good. Maybe the separation between Macro and Handler is necessary from an implementation perspective? But it sure confused me. I didn't expect this differentiation. And still, I have to admit, when programming, I do :Macro, then if it doesn't work, change it to :Handler and see if that works.... 2008/6/26 max demmelbauer <pro...@gm...>: > the Macro | Handler params are needed > > * to check the template-syntax during template-compile-time > * to dont allow access to every variable within templates (i.e. you let the > user modify templates) > * to generate documentation > > if you dont want that check, you can set the failmode="silent" property: > > <% box.get_dimensions.get_value failmode="silent" %> > > in case of an runtime-error (during rendering the template) an empty-string > is returned for this macro. > > ...hmmm... but this behavour is still a work in progress. > > On 26.06.2008, at 17:50, Adrian Smith wrote: > > OK - Thanks for the description. > > I am not sure I agree/understand the difference between a Handler and a > Macro. I mean they could just be the same? > > Sometimes a Macro returns a non-string (e.g. as the input for the "list" > paramter of "foreach") so given that Macros return "anything" - strings, > lists, objects - it would make sense for attributes of them (with the "." > syntax) to be usable. > > I mean in programming languages, you can write: > > - $box > - $box->get_dimensions() > - $box->get_dimensions()->get_width() > > There is no distinction where the first doesn't work at all, the second > only works if get_dimensions is a Macro, and the third only works if > get_dimensions is a Handler. > > But anyway - now I understand the difference (I think) - so it doesn't > matter too much on a practical level for me. > > > > 2008/6/16 max demmelbauer <pro...@gm...>: > >> hmmm.. this is no bug, because you used the macro in a wrong way. >> >> the format of a macro is defined like: >> >> <% handler.handler.macro_name param1="abc" param2=" ... <% ... %> ..." | >> filter1 | filter2 param="..." %> >> >> if you omit the handler (i.e. you want to call a macro in the current >> page) you can write: >> >> <% macro_name param1="abc" param2=" ... <% ... %> ..." | filter1 | filter2 >> param="..." %> >> >> for better understanding you can think the above macro-call is the same >> as: >> >> <% actual_page.macro_name ... %> >> >> (but the handler actual_page dont exists, because it's already the >> default) >> >> >> so to your example: >> >> i think you want to put the current iterator (which is a handler obj) as a >> param to a macro, like: >> >> sub a_macro { >> my ($self, %params) = @_; >> >> return $params{'iterator_obj'}->some_macro(); >> } >> >> but this is not possible because, when you write: >> >> <% a_macro iterator_obj="<% xyz %>" %> >> >> xyz is called as a macro function for the current page (and this is >> exactly the error-msg from your example) >> >> so, there are two solutions for this problem. >> >> 1) our solution with the self macro have done the trick (because it >> returns the handler obj) >> >> 2) handler xyz is already defined for the current page (from the foreach >> macro), so you can write in the macro-code: >> >> sub a_macro { >> my ($self, %params) = @_; >> >> return $self->handler($params{'handler_name'})->some_macro(); >> } >> >> and in the template >> >> <% foreach iterator="xyz" do~q{ >> <% a_macro handler_name="xyz" %> >> } %> >> >> hmmm... i think the second solution is not as nice as the first, because >> you have to split the logic: half in the template (the handler-name) and >> half in macro-code (handler-obj for the handler-name).. and this solution >> also only works in the same page, where the foreach is called. so a >> >> <% foreach iterator="xyz" do~q{ >> <% parent.a_macro handler_name="xyz" %> >> } %> >> >> wouldn't work! >> >> so i think we should implement a general macro which returns the obj of >> the current handler (like your self macro). what would you think is the >> right name for such an macro? >> >> is >> >> sub self :Macro { ... } a good name? >> >> i think its ok, so we should implement this in WebTek/Handler.pm >> >> lg. max. >> >> >> On 15.06.2008, at 13:49, Adrian Smith wrote: >> >> I just searched for ages for this bug! >> >> <% foreach list="...." iterator="xyz" do~q{ >> <% a_macro param="<% xyz %>" %> >> } %> >> >> This doesn't work, producing the error: >> >> macro_error : MyApp::Page::MyPage=HASH(0x227f904) has no macro 'xyz' >> >> If I implement the following method in class Xyz: >> >> sub self :Macro { >> my $self = shift; >> return $self; >> } >> >> and then put the following in the template: >> >> <% foreach list="...." iterator="xyz" do~q{ >> <% a_macro param="<% xyz.self %>" %> >> } %> >> >> Then it works fine >> >> >> > > |