World: r3wp
[Core] Discuss core issues
older newer | first last |
Joe 22-May-2006 [4596] | if is a normal function --> i meant "it is a typical function definition |
Anton 22-May-2006 [4597] | So you want an expanding block of name value pairs to be checked by a function. Something like: [title "Product X website" introduction "Product X is a new way to..." cost 25.90] |
Joe 22-May-2006 [4598x4] | I want the easiest possible approach i.e. you create an html file and define the tags like in the example above template: |
and then you collect with a function the list of tags that you've created and then in a function you go and define dynamically all those tags as variables i.e. title: func-title "xyz" ... | |
I want to use the power of bind and contexts to make sure this works | |
going to lunch. talk to u later thanks | |
Anton 22-May-2006 [4602x2] | Or wait... you want a context to keep all your template variables in: template: context [title: introduction: cost: none] then unset all the variable in the template: unset bind next first template template Your function references words in the template and receives an error for the first one which is unset. f: func [template][do bind [?? title] template] f template ** Script Error: title has no value ** Where: ?? ** Near: mold name: get name but works fine when they have values: template/title: "hello" f template ; ==> title: "hello" |
That should give you some ideas. | |
Ladislav 22-May-2006 [4604] | how about an UNBIND function as follows: |
Joe 22-May-2006 [4605x2] | what is the syntax of unbind ? is it costly to execute ? I would use it unbind the block of variables before creating the template |
i imagine this could be a solution using the global context | |
Ladislav 22-May-2006 [4607x2] | just a moment, testing |
unbind: func [ {unbind words} [catch] words [word! block!] /local word result object ] [ if word? words [words: reduce [words]] result: copy [] unless parse words [ any [set word word! (insert tail result to set-word! word)] ] [throw make error! "unexpected data"] exclude result [self:] insert tail result none object: make object! result either find result first [self:] [first object] [ exclude first object [self] ] ] blk: [a b] a: 1 b: 2 f: func [/local res][ res: bind/copy unbind blk 'res probe reduce res ] f blk | |
Joe 22-May-2006 [4609] | I get script error: self has no value and I get the same error if I set a and b after bind in function f |
Ladislav 22-May-2006 [4610x5] | show me your code, please |
(the code producing the "self has no value" error) | |
Here my understanding would be that a and b are not set in that context and the result is an error. - right, neither 'a nor 'b exists in the function context, therefore they remained global | |
(or unbound, in my version of the function) | |
It looks, that we don't know what exactly you want to accomplish, and it is a bit hard to guess. Could you be more specific? | |
Joe 22-May-2006 [4615x5] | I am using linux and the clipboard doesn't worked so I typed the code |
unbind: func [ "unbind words" [catch] words [word! block!] /local word result object ][ if word? words [words: reduce [words]] result: copy [] unless parse words [ any [set word word! (insert tail result to set-word! word)] ][ throw make error! "unexpected data" ] exclude: result [self:] insert tail result none object: make object! result either find result first [self:] [first object] [ exclude first object [self] ] ] blk: [a b] a: 1 b: 2 f: func [/local res][ res: bind/copy unbind blk 'res a: 1 b: 1 probe reduce res ] f blk | |
** Script Error: self has no value ** Where: f ** Near: self >> | |
I get the same error when commenting a: 1 b: 1 line inside f | |
Ladislav, thank your help. I wanted to ask you about this via the mailing list and I did send the message earlier this morning but the mailing list is down. Please bear with me and I will provide the details. I think the solution you provided is exactly what I was looking for but I might be missing some detail. I am studying your code right now and will be more specific in a few minutes | |
Gregg 22-May-2006 [4620] | Could you write the steps of the problem domain in pseudo-code for us? i.e. forget about the implementation for the moment. |
Joe 22-May-2006 [4621] | i am preparing the pseudo-code. just a few minutes |
Ladislav 22-May-2006 [4622x2] | your code contains the following bug: exclude: result [self:] |
the original line is exclude result [self:] | |
Joe 22-May-2006 [4624x6] | thanks. I will post real code because I think it explains the problem better |
template: to block! "<html><head><title> title </title></head><body>tag1 tag2 tag3</body></html>" blk: remove-each val load copy template [tag? val] ?? blk ; == [title tag1 tag2 tag3] tag3: "this is a fake value, should not appear" eval-template: func [ /local res ][ res: copy "" title: "hey" tag1: "this is tag1^/" tag2: "i am tag 2^/" ;tag3: "might not be set^/" bind/copy template 'res repend res template res ] | |
sorry pls look at the next example | |
template: to block! "<html><head><title> title </title></head><body>tag1 tag2 tag3</body></html>" blk: remove-each val load copy template [tag? val] ?? blk ; == [title tag1 tag2 tag3] tag3: "this is a fake value, should not appear" eval-template: func [ /local res ][ res: copy "" title: "hey" tag1: "this is tag1^/" tag2: "i am tag 2^/" ;tag3: "might not be set^/" bind/copy unbind blk 'res repend res template res ] | |
The unbind function is very close to what I want. In the previous example if the function body does not set the variables a or b it prints [none none]. What I want is that if a variable in blk is not set then it throws an error | |
IPls let me know if this example is not clear. What I want is to catch the case where tag3 is not set and throw an error This is useful where the tags are set in a large function and there are many tags | |
Ladislav 22-May-2006 [4630] | Your EVAL-TEMPLATE function does not have 'TITLE as local variable. Do you want 'TITLE to be local or not? |
Joe 22-May-2006 [4631x2] | I want title to be local without defining it in the spec. Eval template is a function that might be used for many different templates |
IMy understanding is that if you bind a word to the local context then it's a local even if it's not defined in the spec but I probably have multiple misunderstanding (though I just read the Bindology Bible by Ladislav) | |
Ladislav 22-May-2006 [4633x3] | unfortunately that is not true, at least not in this REBOL version |
local contexts are somewhat "static", i.e. they cannot be enlarged | |
(section 15) | |
Gregg 22-May-2006 [4636] | local without defining it in the spec -- I don't think that's a good way to think about modeling it. |
Joe 22-May-2006 [4637] | I see. This is a major limitation. I see the rebol3 has a blog entry that "bind expands contexts" How could I approach this with the current rebol ? |
Anton 22-May-2006 [4638] | No, that's right. Contexts cannot be extended with new words (at this time). I would pass a context to your function with the template and all the words in it. This context will have to be built at the beginning. |
Gregg 22-May-2006 [4639] | It's still not clear to me what the real goal is. i.e. where values come from and how eval-template may be reused without giving it some parameters to guide it. |
Anton 22-May-2006 [4640] | Sorry, I mean you eval-template function can create a context on the fly with the words in it. |
Joe 22-May-2006 [4641] | ok Anton, I will try to implement this with your approach |
Anton 22-May-2006 [4642] | It's not a terribly easy thing to do, but can be done. |
Joe 22-May-2006 [4643] | Gregg, the GOAL is to be able to have a generic eval-template function that can evaluate multiple templates without having to include hundreds of locals in eval template. The values are generated dynamically with a code-block e.g. eval-template template code-block where code-block is [title: func-title "aha" tag1: emit-whatever ... |
Ladislav 22-May-2006 [4644] | hmm, I may not understand your wish, Joe, but don't you want to have it this way? |
Pekr 22-May-2006 [4645] | Today I reread the blog, and I was not comfort with the idea that simple bind should auto-extend context ... maybe just my internal feeling, dunno .... just wanted to state opinion of less experienced reboller :-) |
older newer | first last |