Huhm... so re

> defining globals

According to the API docs: 

*include_string**(code::AbstractString**[**, filename**]**)*

Like include, except reads code from the given string rather than from a 
file. Since there is no file path involved, no path processing or fetching 
from node 1 is done.


But then I think you're right, the code is included / eval'd in Main - so 
it's not really like include(), which provides for mixin behavior? :-O 

duminică, 14 august 2016, 17:13:28 UTC+2, Adrian Salceanu a scris:
>
> Thanks
>
> Maybe I wasn't clear enough - otherwise, can you please elaborate, I'm 
> definitely still poking around, any clarifications would be highly 
> appreciated. 
>
> > creating a new module
> -> the module is available at compile time (the users of the templating 
> system will place the vars in there, by convention). 
>
> > parse julia code
> -> it's not really parsing julia code, it has no meaning at the point. 
> It's simply basic string processing and it's fast - tried with a 10K lines 
> HTML file, no sweat. 
>
> > defining globals 
> -> why are they globals? include_string() is used inside a function, 
> inside a module within the app. 
>
> > eval in a module
> -> true, but then what can we do? That's the way of doing metaprogramming 
> in Julia, and it's widely used, isn't it? 
> I guess that would be the price for not having to do 
> print("<html><head>...") like our ancestors used to in PHP or ASP, when not 
> being chased by tigers (or something around that age). 
>
>
> duminică, 14 august 2016, 15:01:47 UTC+2, Yichao Yu a scris:
>>
>>
>>
>> On Sun, Aug 14, 2016 at 6:13 PM, Adrian Salceanu <[email protected]> 
>> wrote:
>>
>>> Variables contained in a module and then parsed Julia code included 
>>> within a function using include_string(). 
>>>
>>> Any obvious performance issues with this approach? 
>>>
>>
>> Everything about it?
>> Literally every steps are hitting the slow path that is only meant to 
>> execute at compile time and not runtime. Including
>>
>> Creating a new module, parse julia code, eval in a module, defining 
>> globals.
>>  
>>
>>>
>>>
>>> duminică, 14 august 2016, 12:11:06 UTC+2, Adrian Salceanu a scris:
>>>>
>>>> OK, actually, that's not nearly half as bad. Variables contained in a 
>>>> module 
>>>>
>>>> include("src/Ejl_str.jl")
>>>> using Ejl
>>>>
>>>>
>>>> module _
>>>>   couñtry = "España"
>>>>   lang = "en"
>>>> end
>>>>
>>>>
>>>> function render_template()
>>>>   tpl_data = ejl"""
>>>> <% if _.lang == "en" :>
>>>> Hello from me, ...
>>>> <: else :>
>>>> Hola
>>>> <: end %>
>>>>
>>>>
>>>> %= _.couñtry == "España" ? "Olé" : "Aye"
>>>> moo
>>>> """
>>>>
>>>>
>>>>   include_string(join(tpl_data, "\n"))
>>>>   join(____output, "\n")
>>>> end
>>>>
>>>>
>>>> render_template() |> println
>>>>
>>>> Hello from me, ...
>>>>
>>>>
>>>> Olé
>>>> moo
>>>>
>>>>
>>>> duminică, 14 august 2016, 11:20:37 UTC+2, Adrian Salceanu a scris:
>>>>>
>>>>> Thanks
>>>>>
>>>>> Yes, I've thought about a few ways to mitigate some of these issues: 
>>>>>
>>>>> 1. in the app I can setup a module (like Render) and evaluate into 
>>>>> this module exclusively. 
>>>>> Hence, another approach might be to have some helper methods that 
>>>>> setup the variables in the module and then eval the template itself 
>>>>> inside 
>>>>> the module too (must try though). So something in the lines of: 
>>>>> set(:foo, "foo")
>>>>> set(:bar, [1, 2, 3])
>>>>> parse_tpl(ejl"""$(foo) and $(bar)""")
>>>>> # all the above gets parsed in Render
>>>>>
>>>>> 2. break the parsing in 2 steps: 
>>>>> a. reading the template string and parse it to generated Julia code 
>>>>> (as strings) (an array of Julia code lines) - cache it 
>>>>> b. (load strings from cache and) eval the code together with the vars 
>>>>>
>>>>> ===
>>>>>
>>>>> Another approach (which is how it's done in one of the Ruby templating 
>>>>> engine) is to generate a full function definition, whose body parses the 
>>>>> template and takes the variables as params. And then eval and execute the 
>>>>> function with its params. However, I'm still struggling with the 
>>>>> metaprogramming API as for instance parse() chokes on multiple lines, and 
>>>>> I 
>>>>> couldn't find a functional equivalent of a quote ... end blocks. But I'm 
>>>>> hoping include_string() will do the trick (must test though). 
>>>>>
>>>>>
>>>>> sâmbătă, 13 august 2016, 15:20:01 UTC+2, Yichao Yu a scris:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Sat, Aug 13, 2016 at 8:06 PM, Adrian Salceanu <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>> That's pretty difficult as my goal is to use embedded Julia as the 
>>>>>>> templating language. Similar to Ruby's ERB, ex: 
>>>>>>> http://www.stuartellis.eu/articles/erb/
>>>>>>>
>>>>>>> So say in the template I have something like 
>>>>>>>
>>>>>>> <% if foo == "bar" %>
>>>>>>> Bar
>>>>>>> <% else %>
>>>>>>> Baz
>>>>>>> <% end %>
>>>>>>>
>>>>>>> The idea is to use Julia itself to parse the code block and Julia 
>>>>>>> will raise an error is foo is not defined. So I can't really look it 
>>>>>>> up. 
>>>>>>>
>>>>>>
>>>>>> It's ok to use the julia syntax and parser but it's a pretty bad idea 
>>>>>> to use the julia runtime to actually evaluating the expression, and 
>>>>>> absolutely not by making them reference to local variables.
>>>>>>
>>>>>> For a start you are not allowed to reference local variables by names 
>>>>>> anyway.
>>>>>> You also shouldn't allow reference to/overwrite of other local 
>>>>>> variables (i.e. the template namespace should be fully isolated and 
>>>>>> independent of any scope in the template engine).
>>>>>>
>>>>>> Since you want to eval, it seems that efficiency is not an issue, in 
>>>>>> which case you can create an anonymous module and eval/create globals in 
>>>>>> that module. This should also be reasonably fast if you are only using 
>>>>>> the 
>>>>>> template once.
>>>>>>
>>>>>> If you want to use it multiple time and compile the template, you 
>>>>>> should then scan for variable references in the expressions and process 
>>>>>> it 
>>>>>> from there.
>>>>>>  
>>>>>>
>>>>>>>
>>>>>>> I can either do 
>>>>>>>
>>>>>>> <% if _[:foo] == "bar" %> 
>>>>>>>
>>>>>>> or 
>>>>>>>
>>>>>>> <% if _(:foo) == "bar" %>
>>>>>>>
>>>>>>> but it's not that nice. 
>>>>>>>
>>>>>>>
>>>>>>> sâmbătă, 13 august 2016, 13:24:18 UTC+2, Yichao Yu a scris:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On Sat, Aug 13, 2016 at 7:13 PM, Adrian Salceanu <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Thanks
>>>>>>>>>
>>>>>>>>> It's for a templating engine. The user creates the document (a 
>>>>>>>>> string) which contains interpolated variables placeholders and 
>>>>>>>>> markup. When 
>>>>>>>>> the template is rendered, the placeholders must be replaced with the 
>>>>>>>>> corresponding values from the dict.
>>>>>>>>>
>>>>>>>>> The lines in the template are eval-ed and so Julia will look for 
>>>>>>>>> the variables in the scope. So the vars should be already defined.
>>>>>>>>>
>>>>>>>>
>>>>>>>> You should explicitly look up those variables in the dict instead.
>>>>>>>>  
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Yes, ultimately I can force the user to use a dict (or rather a 
>>>>>>>>> function for a bit of semantic sugar) - which is preferable from a 
>>>>>>>>> performance perspective, but less pretty end error prone from the 
>>>>>>>>> user 
>>>>>>>>> perspective.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>
>>

Reply via email to