<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>MouseOver Studio &#187; jsr</title>
	<atom:link href="http://www.mouseoverstudio.com/blog/category/jsr/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.mouseoverstudio.com/blog</link>
	<description></description>
	<pubDate>Wed, 25 Aug 2010 02:03:38 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
	<language>en</language>
			<item>
		<title>Apresentando CompiledScript e Compilable para melhorar a performance de teus programas JRuby e similares</title>
		<link>http://www.mouseoverstudio.com/blog/2008/08/31/apresentando-compiledscript-e-compilable-para-melhorar-a-performance-de-teus-programas-jruby-e-similares/</link>
		<comments>http://www.mouseoverstudio.com/blog/2008/08/31/apresentando-compiledscript-e-compilable-para-melhorar-a-performance-de-teus-programas-jruby-e-similares/#comments</comments>
		<pubDate>Sun, 31 Aug 2008 04:05:14 +0000</pubDate>
		<dc:creator>Diego Carrion</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[jruby]]></category>

		<category><![CDATA[jsr]]></category>

		<category><![CDATA[optimizacao]]></category>

		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.mouseoverstudio.com/blog/?p=119</guid>
		<description><![CDATA[Quando avaliamos alguma script na JVM utilizando o método eval da classe javax.script.ScriptEngine basicamente são realizadas duas tarefas: a compilação do script e a execução dele.
Caso queiramos avaliar x vezes o mesmo script e estejamos chamando o método eval mencionado, o script ira ser compilado x vezes.
O mesmo script precisa ser compilado x vezes?
Não!
O que [...]]]></description>
			<content:encoded><![CDATA[<p>Quando avaliamos alguma script na JVM utilizando o método <em>eval</em> da classe <em>javax.script.ScriptEngine</em> basicamente são realizadas duas tarefas: a compilação do script e a execução dele.</p>
<p>Caso queiramos avaliar x vezes o mesmo script e estejamos chamando o método <em>eval</em> mencionado, o script ira ser compilado x vezes.</p>
<p><strong>O mesmo script precisa ser compilado x vezes?</strong></p>
<p>Não!</p>
<p><strong>O que fazer ao respeito?</strong></p>
<p>A especificação JSR-233 conta com uma classe chamada <em>CompiledScript</em> que como o mesmo nome diz, representa um script compilado, de modo que quando queiramos avaliar o script o único que vamos ter que fazer é executar ele.</p>
<p>Para compilar um script primeiro temos que realizar um casting do engine para a interfase Compilable e logo chamar o metodo <em>compile</em>:</p>
<pre class="prettyprint">CompiledScript compiledScript = ((Compilable) engine).compile(script)</pre>
<p>Logo, quando queiramos avaliar o script compilado o único que vamos ter que fazer e chamar o método <em>eval</em>, passando como parâmetro o contexto (opcional):</p>
<pre class="prettyprint">Object result = compiledScript.eval(context)</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mouseoverstudio.com/blog/2008/08/31/apresentando-compiledscript-e-compilable-para-melhorar-a-performance-de-teus-programas-jruby-e-similares/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Interpretando Ruby e outras linguagens de script dentro da plataforma Java</title>
		<link>http://www.mouseoverstudio.com/blog/2008/08/29/interpretando-ruby-e-outras-linguagens-de-script-dentro-da-plataforma-java/</link>
		<comments>http://www.mouseoverstudio.com/blog/2008/08/29/interpretando-ruby-e-outras-linguagens-de-script-dentro-da-plataforma-java/#comments</comments>
		<pubDate>Fri, 29 Aug 2008 03:02:42 +0000</pubDate>
		<dc:creator>Diego Carrion</dc:creator>
		
		<category><![CDATA[java]]></category>

		<category><![CDATA[jruby]]></category>

		<category><![CDATA[jsr]]></category>

		<category><![CDATA[ruby]]></category>

		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://www.mouseoverstudio.com/blog/?p=118</guid>
		<description><![CDATA[Para poder criar o Haml4j sem a necessidade de reinventar a roda teve que poder aproveitar o código Ruby já existente. Existem vários jeitos de interpretar código Ruby na JVM. Um de eles é utilizando o engine do JRuby para o BSF (Bean Script Framework), do Apache. Outro jeito é utilizando o JRuby puro, como [...]]]></description>
			<content:encoded><![CDATA[<p>Para poder criar o <a href="http://www.mouseoverstudio.com/blog/?p=117">Haml4j</a> sem a necessidade de reinventar a roda teve que poder aproveitar o código Ruby já existente. Existem vários jeitos de interpretar código Ruby na JVM. Um de eles é utilizando o engine do JRuby para o <a href="http://jakarta.apache.org/bsf/">BSF</a> (Bean Script Framework), do Apache. Outro jeito é utilizando o JRuby puro, como foi mostrado <a href="http://codezone.wordpress.com/2008/08/14/executar-jruby-a-partir-do-java/">aqui</a>. O terceiro jeito, e do qual eu gostei mais, é utilizando a implementação JRuby para à especificação <a href="http://jcp.org/en/jsr/detail?id=223">JSR-233</a>, que define o uso das diferentes linguagens de script na plataforma Java.</p>
<p>Existem bons documentos que explicam como trabalhar com JRuby utilizando a especificação JSR-233 <a href="http://wiki.jruby.org/wiki/Walkthroughs_and_Tutorials#JSR_223_scripting">aqui</a>, porém, eles estão todos em inglês e é por tal motivo que eu vou falar aqui sobre como a coisa funciona.</p>
<p>Antes de que me esqueça, é importante lembrar que o que ira ser mostrado aqui se aplica tanto a JRuby como a JavaScript ou qualquer outra linguagem de script, devido a que estamos trabalhando sobre a especificação e não sobre a implementação. A implementação é utilizada de forma transparente.</p>
<p>Quando queremos interpretar algum script, o primeiro que temos que fazer é obter uma instancia do engine para o tipo de script que queremos interpretar. A classe que nos oferece tais engines é ScriptEngineManager. Gostaria que o método para requerer certo engine fosse estático, mas não, temos que criar uma instancia dele para logo solicitar o engine, assim:</p>
<pre class="prettyprint">ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("jruby");
</pre>
<p>Reparem no seus imports que não fazemos referencia a nada do JRuby. Isso é muito legal. Caso amanha saia um interpretador do Ruby melhor que o JRuby e desejemos utilizar ele, o único que vamos ter que fazer e mudar o parâmetro do método getEngineByName. Claro, sempre e quando o interpretador implemente a especificação.</p>
<p>Quando mandamos nosso engine escolhido interpretar algum script, podemos indicar à ele qual contexto utilizar. Um contexto é como um espaço ou espoco onde colocamos diversos objetos Java, os quais iram ser tratados como variareis globais na hora da interpretar os scripts. Podemos ter diversos contextos. Segue um exemplo:</p>
<pre class="prettyprint">engine.put("language", "portuguese");
engine.eval("puts 'You choose #{$language}'");
ScriptContext newContext = new SimpleScriptContext();
newContext.setAttribute("language", "spanish", ScriptContext.ENGINE_SCOPE);
engine.eval("puts 'You choose #{$language}'", newContext);</pre>
<p> O contexto possui um mapa de chaves e valores. Na primeira linha do exemplo colocamos o valor <em>portuguese</em> para a chave <em>language</em> no contexto default. Quando não indicamos nenhum contexto, o engine pega os valores do contexto default e por tal motivo a segunda linha ira imprimir <em>You choose portuguse</em>. Na terceira linha criamos um segundo contexto e na quarta linha indicamos o valor <em>spanish</em> para a mesma chave utilizada anteriormente: <em>language</em>. Reparem que o método setAttribute aceita um segundo parâmetro que pode ser ScriptContext.ENGINE_SCOPE ou ScriptContext.GLOBAL_SCOPE. Esse segundo parâmetro é algo que ainda não entendi direito. Na teoria, ENGINE_SCOPE indica que o mapeamento se aplica somente ao engine em questão, à diferença de GLOBAL_SCOPE que indicaria que o mapeamento é para todos os engines. O problema é que eu não tenho nenhum engine relacionado com tal contexto, pelo que indicar um escopo ao contexto não teria sentido. Somente para terminar esse exemplo, a ultima linha ira utilizar o contexto criado e devido a isso ira imprimir <em>You choose spanish</em>.</p>
<p>O método eval retorna o resultado da interpretação do script. No exemplo o resultado seria nil. Para termos uma idéia do valor a ser devolvido poderíamos utilizar o Jirb:</p>
<pre class="prettyprint">dcrec1:~ dcrec1$ jirb
irb(main):001:0> puts "You choose portuguese"
You choose portuguese
=> nil
irb(main):002:0> 1 + 2
=> 3
irb(main):003:0> a = 5
=> 5
irb(main):004:0> a
=> 5
irb(main):005:0> require 'rubygems'
=> true
irb(main):006:0> require 'haml'
=> true</pre>
<p>O método eval retorna uma instancia da classe Object, pelo que o resultado precisa passar por um processo de casting. Segue um exemplo tomado da primeira versão do Haml4j:</p>
<pre class="prettyprint">String result = (String) engine.eval("Haml::Engine.new($haml).render");</pre>
<p>Agora imaginemos que numa dessas chamadas ao método eval o engine interpretou uma definição de função ou de uma classe com métodos. Se queremos executar uma das funções interpretadas, não precisamos chamar de novo o método eval com o nome da função e os parâmetros concatenados como uma string. Nesse caso podemos declarar um objeto invocável e invocar ele passando como parâmetro a função desejada e os parâmetros, assim:</p>
<pre class="prettyprint">Invocable invocable = (Invocable) engine;
String randomText = (String) invocable.invokeFunction("generate_random_text");
Object car = invocable.invokeFunction("create_a_new_car", "blue", "automatic");</pre>
<p>Na primeira linha definimos um objeto invocável e na segunda executamos a função generate_random_text, que sabemos devolve uma string e por isso fazemos um casting. Na terceira linha executamos a função create_new_car passando como parâmetros blue e automatic. Nesse caso não fizemos nenhum casting porque o resultado é um objeto do Ruby (poderia ser de qualquer linguagem). Nosso objeto chamado car tem alguns métodos e agora vamos chamar um deles:</p>
<pre class="prettyprint">int speed = (Integer) invocable.invokeMethod(
      car, "max_speed", 100);</pre>
<p>Acabamos de chamar o método max_speed (segundo parâmetro) do objeto car (primeiro parâmetro) passando como parâmetro 100. Esse terceiro parâmetro esta estranho mas imaginemos que o método calcula a velocidade máxima que o carro pode alcançar para um peso determinado.</p>
<p>No caso que nossas funções ou métodos invocáveis façam referencia a alguma variável global, podemos definir o valor dela chamando o metodo put:</p>
<pre class="prettyprint">invocable.put("country", "Brazil");</pre>
<p>Com o mostrado aqui da tranqüilamente para começar a utilizar scripts legais em Ruby ou outra linguagem de script dentro da plataforma Java. Espero que no futuro apareçam muitos projetos brasileiros legais. Ficarei no aguardo. Aliais, ficarei tentando eu mesmo criar um <img src='http://www.mouseoverstudio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mouseoverstudio.com/blog/2008/08/29/interpretando-ruby-e-outras-linguagens-de-script-dentro-da-plataforma-java/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
