r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Core] Discuss core issues

Joe
22-May-2006
[4648]
What I've been using in the past is different versions of eval-template 
for each template and I found the typical bug to be when missing 
a local given that the templates are evaluated multiple times
Anton
22-May-2006
[4649]
After extracting the words you need to convert them all to set-words 
and put them in a spec block, eg:
spec: copy []
foreach word words [append spec to-set-word word]
append spec none
; now you can create the context using the spec
the-context: context spec
; now unset each word in the context, etc..
Joe
22-May-2006
[4650]
Yes anton, I will code it this way. I am worried that unbinding the 
words every time is a performance hit
Anton
22-May-2006
[4651]
Possibly, we can optimize it later. Binding is supposed to be pretty 
fast in rebol.
Joe
22-May-2006
[4652]
Ladislav, I will try to communicate better. What do you mean by "don't 
want to have it this way ?"
Ladislav
22-May-2006
[4653x2]
eval-template: func [
    template
    /local res
] [do something with the template...]
I just thought, that you wanted to have a function accepting and 
processing templates
Joe
22-May-2006
[4655]
Yes, my problem is an error handling problem. So far the template 
blocks are global, and I want to have functions that can build the 
templates without actually passing the template as a parameter
Ladislav
22-May-2006
[4656]
it looks, that you actually don't need UNBIND
Gregg
22-May-2006
[4657x2]
Could I ask again for pseudo-code? I'm having the same problem as 
Ladislav I think.
If we could step back and look at the problem, without implementation 
details, it would help me to understand.
Anton
22-May-2006
[4659]
Yes, it's a bit confusing jumping straight into it like this.
Gregg
22-May-2006
[4660x2]
I'm only asking because I think you're making this a lot harder than 
it needs to be, but I can't be sure if I don't understand the problem.
I've found that I can make things hard for myself, if I fight REBOL, 
or easy, if I don't.  :-)
Anton
22-May-2006
[4662]
Yes, I can't say I find myself needing to do such an operation very 
often. Been a while since I generated html though.
Joe
22-May-2006
[4663x4]
a new attempt. The code that follows works except that I have to 
define the tags as locals, which is a pain when there are lots of 
them
template:  	to block!  "<html><head><title> title </title></head><body>tag1 
tag2 tag3</body></html>"

blk:		remove-each val copy template [tag? val]	 ?? blk ; == [title 
tag1 tag2 tag3]

eval-template: func [
	/local res title tag1 tag2 tag3
][
	res: 		copy ""

	bind/copy 	blk 'res

	title: 		"hey"
	tag1: 		"this is tag1^/"
	tag2: 		"i am tag 2^/"
	;tag3: 		"might not be set^/"

	repend 		res bind/copy template 'res
	res
]


probe eval-template
so in this example tag3 is none because it was not set in the body 
but this is clearly an error. I am trying to solve 2 things:
1) Not having to declare the locals title tag1 tag2 tag3 in the function 
spec but have them as locals (might not be possible)
Ladislav
22-May-2006
[4667]
that *is* possible if needed
Joe
22-May-2006
[4668x2]
2) detect when one of the variables has not been set  . In the above 
example with locals defined this can easily be fixed by checking 
for tags that are none
Ladislav, then if there is an elegant way to define the locals inside 
the function body given blk: [title tag1 tag2 tag3] my problem is 
solved
Gregg
22-May-2006
[4670]
Why not just use FUNCTION with your existing code body and spec; 
make eval-template funcs on the fly?
Anton
22-May-2006
[4671x2]
You would have to define a function every time, yes.
(for the same reason - contexts can't be extended with new words).
Joe
22-May-2006
[4673]
Yes,  but how costly is this ? ( I currently can generate 1000 pages/minute)
Gregg
22-May-2006
[4674]
I would still lean towards a higher level solution at some point, 
but this makes more sense to me than messing with bindings.
Ladislav
22-May-2006
[4675]
;This is one way how to do it:
eval-template: lfunc [template [string!]][] [
	res: 		copy ""

	bind/copy 	blk 'res

	title: 		"hey"
	tag1: 		"this is tag1^/"
	tag2: 		"i am tag 2^/"
	;tag3: 		"might not be set^/"

	repend 		res bind/copy to block! template 'res
	res
]

see http://www.fm.tul.cz/~ladislav/rebol/lfunc.rThis would throw 
an error if the tag3: line is commented
Gregg
22-May-2006
[4676]
Profile it. :-) How many do you *need* to generate, how much data, 
how many tags, etc. There are a lot of variables here (no pun intended).
Joe
22-May-2006
[4677x2]
there are three approaches so far: 1) building function everytime 
with locals (anton/gregg) 2) template object (anton) and 3) lfunc
I am going to code this using lfunc for the simplicity it brings 
and see what I learn Thanks all
Ladislav
22-May-2006
[4679]
the LFUNC approach would cause an error if the 'TAG3 variable were 
used in the template, otherwise it wouldn't cause an error. Is that 
what you wanted?
Anton
22-May-2006
[4680]
(if your templates are not changing, the corresponding template objects 
can be made once and reused many times).
Joe
22-May-2006
[4681x3]
Ladislav, yes
Anton, can you code the above example using the template object you 
proposed
Maybe lfunc should be something part of Rebol3 .
Ladislav
22-May-2006
[4684]
:-)
Anton
22-May-2006
[4685x3]
ok, hang five.
Paste this into your console:
make-template-context: func [
	template
	/local words spec
][
	words: remove-each val to-block template [tag? val]

	spec: words
	forall spec [spec/1: to-set-word spec/1]
	append spec none

	context spec	
]

eval-template: func [
	template-ctx
	code
	/local err
][

 unset bind next first template-ctx template-ctx  ; unset all words 
 in the context
	do bind code template-ctx  ; do the code

	; Check if any tags were not set

 if find next second template-ctx unset! [ ; were any tags not set 
 ?
		print "Some tags were not set!"
		foreach word next first template-ctx [
			if not value? in template-ctx word [
				print [word "is unset!"]
			]
		]
	]
]

; now test


template: "<html><head><title> title </title></head><body>tag1 tag2 
tag3</body></html>"

template-context: make-template-context template

eval-tags: [
	title: "web page"
	tag1: "tag1"
	tag2: "tag2"
	tag3: "tag3"
]


eval-template template-context eval-tags  ; <- this sets all expected 
tags and is ok

eval-template template-context [] ; <- this doesn't set any tags 
so will complain and show all unset tags
Joe
22-May-2006
[4688]
I am using altme on linux. How do I get the clipboard to work ?
Henrik
22-May-2006
[4689]
I think by using the middle mouse button
Joe
22-May-2006
[4690x2]
nope, clipboard is broken in linux
anton, thanks for your example, it's quite useful
Anton
22-May-2006
[4692]
You're welcome.
Joe
22-May-2006
[4693x2]
ZZ
didn't mean to type it
Frank
22-May-2006
[4695]
Clipboard on linux :   ctrl-v  in altme and middle mouse button in 
a text editor, it works for me
Joe
22-May-2006
[4696]
Frank, yes thanks. For me is ctrl-C + middle mouse
Henrik
22-May-2006
[4697]
Why can't I find paths in a loadable block?

>> t: [x/y]
== [x/y]
>> type? first t
== path!
>> find t 'x/y
== none
>> find t to-path 'x/y
== none