Clipper On Line • Ver Tópico - Codeblock para String, tem como? - Harbour
Página 1 de 2

Codeblock para String, tem como? - Harbour

MensagemEnviado: 09 Mai 2011 12:20
por Pablo César
Peguei carona neste tópico...

Tenho uma matriz, onde um elemento é do tipo "B", seria CodeBlock ? Tem como exibir (não executar) esse conteúdo do elemento ? Preciso saber o que diz esse codeblock. Alguém sabe me dizer como exibo em forma de caracter esse elemento ?
Em outras palavras, preciso transformar o codeblock em string para pode exibir em tela e/ou concatenar com outra string. Alguém sabe dizer como posso fazer isso ?

O CLD do Clipper, mostra o um codeblock. Quero sabe como faz isso.

Nota de Moderação:
por Pablo César: Tópico movido por conter soluções seomente em Harbour

Codeblock para String, tem como?

MensagemEnviado: 09 Mai 2011 13:23
por anacatacombs
Pablo César escreveu:onde um elemento é do tipo "B", seria CodeBlock ?

Sim.

Pablo César escreveu:preciso transformar o codeblock em string para pode exibir em tela e/ou concatenar com outra string


Desconheço alguma função que mostre esse resultado. Até deve ter , mas eu particularmente não conheço.

Mas me diga meu querido... pq vc precisa mostrar em tela e/ou concatenar um bloco de código com com uma string? O resultado do bloco de código é uma string?

[]'s

Ana

Codeblock para String, tem como?

MensagemEnviado: 09 Mai 2011 13:35
por Pablo César
Oi Ana, obrigado pelo seu interesse e resposta. Estou aprofundando-me um pouco mais em HMG e sei que a matriz interna _HMG_SYSDATA guarda valiosas informações. Uns dos tantos dos elementos são do tipo codeblock e gostaria tomar conhecimento do conteúdo para poder entendê-los. Claro que o Roberto Lopez (pai da criança) desaconselha a manipulação desta matriz. Estou querendo mudar as cores da barra de navegação do browse quando este for registro deletado (isso claro quando o SET DELETED estiver setado em OFF). Também sei que posso interagir em C e quem sabe mudar esse atributo com uma função externa feito em C. Isso por mero capricho meu, nada tão importante. Mas chamou a minha atenção não poder obter o conteúdo de tais elementos, pois estou gravando em arquivo todo o conteúdo da matriz a fim de poder analisá-la durante e após a execução do aplicativo feito em HMG.

Codeblock para String, tem como?

MensagemEnviado: 09 Mai 2011 13:58
por sygecom
Olá Nobert,
Não sei em Clipper, mas em xHarbour tem uma função que uso para guardar um codeblock em string para ser executada aleatoriamente pelo usuário, veja se o exemplo abaixo ajuda:
bBloco = { || Funcao() }
cSTRING_BLOCK:=valtoprg(bBloco)

Codeblock para String, tem como?

MensagemEnviado: 09 Mai 2011 14:08
por anacatacombs
Entendi. Quando vc executa esse bloco de código com o Eval, o que o danado retorna?
Pensei na ValtoPrg também, mas não sei se existe algo semelhante em clipper..

Codeblock para String, tem como?

MensagemEnviado: 09 Mai 2011 14:46
por Pablo César
sygecom escreveu:Olá Nobert
KKK ahhh você me faz rir Leonado... você sempre apressado... nem viu que era eu quem estava perguntando. Eu só aproveitei o tópico que tratava do mesmo assunto, mas o tópico é de 2005, hihihihi

Mas obrigado Leonardo, serviu para pesquisar sobre mensagens relacionadas. Mas com o ValtoPrg não funcionou como esperado. Compilar em HMG 3.0.35 ele vai mas o retorno deu vazio lendo a matriz e em outra tentativa deu erro Warning/0 ao executar o seu exemplo:
bBloco = { || Funcao() }
cSTRING_BLOCK:=valtoprg(bBloco)

Como disse, procurei e achei uma mensagem do Itamar em outro site que indicavam o uso do HB_ValToExp e
este retornou: "{|| ... }" mas sem nada dentro das chaves.

Ana escreveu:Quando vc executa esse bloco de código com o Eval, o que o danado retorna?
Quando executo com EVAL ele apenas executa a ação mas dá erro pois estou concatenando (gravando o retorno em arquivo) e dá erro de "+".
Pensei na ValtoPrg também, mas não sei se existe algo semelhante em clipper..
Mas não deu certo com ValtoPrg. Quanto a ser em Clipper, eu apenas aproveitei o tópico aqui em Clipper, pois a solução poderia servir para Harbour pois a minha aplicação é em Harbour (lamento a confusão). Acho que terei que desdobrar o tópico e transferir para a seção Harbour, pois não parece haver solução em Clipper. Sei que estou perto, mas bom seria conseguir ler o que tem dentro das chaves.

Codeblock para String, tem como?

MensagemEnviado: 09 Mai 2011 14:55
por anacatacombs
É, serial legal para caso outra pessoa também precise extrair essas informações.

Bom, sabemos que não retorna uma string, pois deu argument error + ao tentar concatenar.
Manda um VALTYPE pra ver que tipo ele retorna, pra dar uma mensagem.. esse bloco deve retornar algo.
Não sei como tá estruturado, mas fiz um teste simples:

B_Pablo:= {|| "Pablo" }
??  EVAL(B_Pablo)  -> Retornou "Pablo"


Ou Tente

?? VALTOPRG(EVAL(bBlock))

Codeblock para String, tem como?

MensagemEnviado: 09 Mai 2011 15:05
por Pablo César
B_Pablo:= {|| "Pablo" }
??  EVAL(B_Pablo)  -> Retornou "Pablo"
Mas o certo seria sem aspas. Desse jeito seria uma string e não o codeblock.
Manda um VALTYPE pra ver que tipo ele retorna
e
?? VALTOPRG(EVAL(bBlock))
Abortam na tentativa de execução.

O que mais deu certo até agora é o HB_ValToExp mas faltou informação dentro das chaves...

Codeblock para String, tem como? - Harbour

MensagemEnviado: 09 Mai 2011 15:23
por sambomb
Tente:
#command Exibe <var> => Alert(<"var">)
#command Exibe <var> => Alert(#<var>)

Exibe bBloco

Obs.: não testei

Codeblock para String, tem como? - Harbour

MensagemEnviado: 09 Mai 2011 15:33
por Pablo César
Não estou em modo console, mas substituí o seu ALERT por MsgInfo que daria o mesmo, só para exibir em tela. E resultou em exibir a palavra bBloco e mesmo fazendo outro teste utilizando o mesmo comando mas lendo direto da matriz onde se encontram o codesblocks, também sempre retorna o "nome" da variável após comando Exibe.

Codeblock para String, tem como? - Harbour

MensagemEnviado: 09 Mai 2011 15:51
por anacatacombs
Pablo César escreveu:Mas o certo seria sem aspas. Desse jeito seria uma string e não o codeblock.


Não querido. É um bloco de código com uma string.. se fosse uma string daria erro ao executar com o EVAL, não é?
Sem a string, daria erro de execução - Creio que iria procurar pela variavel PABLO, e não a string.

Se a função o retornou {||...} , é pq retornou um bloco de código... não vai aparecer o resultado no meio ..

Você sabe que no bloco de código tem uma string, certo? e quer pegar essa danada pra fazer qualquer coisa depois não é? Primeiro precisamos saber o que tem nesse bloco de código. Pode ser uma função retornando .T., .F. ou NIL, pode ser uma variavel, etc etc etc.. por isso pedi pra vc executar e verificar o que ele retorna.
Qual erro dá?

Vc precisa disso mesmo ou eu entendi errado???

Codeblock para String, tem como? - Harbour

MensagemEnviado: 09 Mai 2011 16:10
por Pablo César
Ana escreveu:
Pablo César escreveu:Mas o certo seria sem aspas. Desse jeito seria uma string e não o codeblock.
Não querido. É um bloco de código com uma string.. se fosse uma string daria erro ao executar com o EVAL, não é?
Sem a string, daria erro de execução - Creio que iria procurar pela variavel PABLO, e não a string.
Não eu acho que buscaria a "função" Pablo e não a variável. Você viu a indicação do Leonardo ? O codeblock que ele postou estava sem aspas após as chaves. Em vários exemplos que peguei sobre codeblocks, sempre estão assim, por exemplo: {||MsgInfo('Click 1')} viu ? Sem aspas.

Se a função o retornou {||...} , é pq retornou um bloco de código... não vai aparecer o resultado no meio ..
Este resultado foi obtido utilizando HB_ValToExp(). E pode ser, mas retorno em forma de string, senão não daria para concatenar e gravar em arquivo.

Você sabe que no bloco de código tem uma string, certo?
Acredito que deva ter uma chamada de função.
e quer pegar essa danada pra fazer qualquer coisa depois não é? Primeiro precisamos saber o que tem nesse bloco de código.
Gostaria mesmo eu de saber. São mais de 10 codesblocks que essa matriz deve ter.

Pode ser uma função retornando .T., .F. ou NIL, pode ser uma variavel, etc etc etc.. por isso pedi pra vc executar e verificar o que ele retorna.Qual erro dá?
Não dá erro algum, apenas aborta a aplicação.

Vc precisa disso mesmo ou eu entendi errado???
Acho que a linha de análise está no rumo certo, só não entendo por quê não consigo sabe o que tem em cada codeblock. Pois o ValeType retorna "B" mas só exibe {|| ... } quando utilizo HB_ValToExp(). Já seu eu aninhar deste jeito: ValtoPrg(HB_ValToExp(variável ou elemento))"{|| ... }" (entre aspas). Mas sempre vazio, aliás com três pontinhos, sem informação.

Uma pena, não saber ler o codeblock e tranformar em string. Acho que estamos pecando nisso.

Codeblock para String, tem como? - Harbour

MensagemEnviado: 09 Mai 2011 16:18
por anacatacombs
Certa vez, um colega de trabalho também queria extrair essa informação, mas a lógica do rapaz não estava certa, resolvemos o problema utilizando as funções corretas.

Mais uma pra galeria "só pra ter certeza", eu testei, e retornou Variavel não existe.. realmente ele buscou pela variavel.. com () ele busca pela função.
Pablo César escreveu: {||MsgInfo('Click 1')} viu ? Sem aspas.


Claro, é uma função.. por isso sem aspas.. eu só coloquei as aspas pra simular uma string, não uma função ou uma variavel. Eu pensei que vc tinha uma string dentro de um bloco de código e queria extrair essa string.

Talvez algum colega possa executar tal façanha.

Desculpe não poder ajudar :(

Codeblock para String, tem como? - Harbour

MensagemEnviado: 09 Mai 2011 16:31
por Pablo César
Pois é, Ana, algo deve estar fora de padrão ou não conhecemos outr função em Harbour que transforme codeblocks em string. Eu de cabeça, sei que existe outra função algo assim: ????tostring() mas não lembro e quem sabe funcionasse.

Codeblock para String, tem como? - Harbour

MensagemEnviado: 09 Mai 2011 18:04
por sambomb
HB_Serialize()
Converts an arbitrary value to a binary string.
Syntax
HB_Serialize( <xValue> ) --> cBinary

Arguments
<xValue>
This is an arbitrary value to convert to a binary string. The value can be of any data type, except Pointer. Return
The function returns the binary representation of <xValue> as a character string.

Description

Function HB_Serialize() converts an arbitrary value to its binary string representation. The binary string can then be treated like a regular character string and written to a file, for example. The original value can be obtained by passing the binary string to HB_DeSerialize().
Although values of any data type can be passed to the function, certain limitations must be complied with when values are (de)serialized:
Simple data types
There is no limit for the serialization of values having the data type Character, Date, Numeric, Logic or NIL
Arrays and Hashes
No limitation exists for arrays and hashes when their elements contain values of simple data types. Nested arrays and hashes can be serialized as long as they do not reference themselves in their elements. When complex data types are stored in arrays or hashes, the same limitations as for the respective data type exist for arrays and hashes.
Code blocks
As a general rule, only code blocks that access items having a symbolic name at runtime can be serialized. This excludes code blocks referencing GLOBAL, LOCAL or STATIC variables and/or STATIC FUNCTIONs and PROCEDUREs from conversion, since their symbolic names do not exist at runtime. Passing such a code block to HB_Serialize() generates a runtime error.
The code block can only be deserialized in the exact same binary that converted the code block. That means, only executables that are created with the same PCode version of xHarbour and have the same symbol table can deserialize a serialized code block.
Objects
The same limits as for code blocks exist for objects. It is recommended to subclass from the HBPersistent() class when objects should be serialized.
Pointers
Pointers cannot be serialized since they refer to memory locations at runtime. HB_Serialize() returns always NIL when a pointer is passed.
Info

See also: HB_Deserialize(), HB_SerializeSimple(), HB_SerialNext(), RESTORE, SAVE
Category: Conversion functions , Serialization functions , xHarbour extensions
Source: rtl\hbserial.prg
LIB: xhb.lib
DLL: xhbdll.dll

Example
// In this example, a code block is created and stored in a MEM file.
// The second invocation of the example code loads the stored code block
// and evaluates it. Note that the code block referenes a PRIVATE variable
// that is restored along with the code block.

PROCEDURE Main
LOCAL bBlock := {|| Alert( pcString ) }

IF .NOT. File( "Codeblock.mem" )

PRIVATE pcString := "code block restored from file"
PRIVATE pcBlock := HB_Serialize( bBlock )

SAVE TO Codeblock.mem ALL LIKE pc*
? "Restart program to load code block"

ELSE
RESTORE FROM Codeblock.mem

bBlock := HB_DeSerialize( pcBlock )

Eval( bBlock )
ENDIF

RETURN


HB_SaveBlock()
Utility function for code block serialization.

Syntax
HB_SaveBlock( <bCodeblock> ) --> aCodeBlockInfo

Arguments
<bCodeblock>
This is the codeblock to convert to a binary form. Return
The function returns an array holding information about the serialized code block.

Description
HB_SaveBlock() converts a code block to its binary representation and collects this information in an array, which is returned. The array can be passed to HB_RestoreBlock() to rebuild the code block. The function is a utility function internally used by HB_Serialize(). Refer to this function for limitations on code block serialization.
Info

See also: HB_DeSerialize(), HB_RestoreBlock(), HB_Serialize(), RESTORE, SAVE
Category: Code block functions , Conversion functions , xHarbour extensions
Source: vm\hvm.c
LIB: xhb.lib
DLL: xhbdll.dll

Codeblock para String, tem como? - Harbour

MensagemEnviado: 09 Mai 2011 19:55
por Pablo César
Dessas funções só conseguí testar a HB_Deserialize() mas obteve retorno vazio (2 espaços). Talvez porque sejam para xHarbour.
Lamentavelmente ainda fico sem ler os codeblocks dessa matriz.

Codeblock para String, tem como? - Harbour

MensagemEnviado: 09 Mai 2011 21:51
por sygecom
Puxa Pablo,
Pablo César escreveu:KKK ahhh você me faz rir Leonado... você sempre apressado... nem viu que era eu quem estava perguntando. Eu só aproveitei o tópico que tratava do mesmo assunto, mas o tópico é de 2005, hihihihi


Mas obrigado Leonardo, serviu para pesquisar sobre mensagens relacionadas. Mas com o ValtoPrg não funcionou como esperado. Compilar em HMG 3.0.35 ele vai mas o retorno deu vazio lendo a matriz e em outra tentativa deu erro Warning/0 ao executar o seu exemplo:

Sei lá o que você fez ai, mas fiz um teste rapido aqui com uma função do clipper mesmo e me mostrou um monte de CHR() que é assim mesmo que ele guarda o CODE, no meu caso aqui eu guardo o CODEBLOCK do ACTION dos MENUS para ser executados nos atalhos que são criado em tempo de execução em Hwgui + xHarbour.

Exemplo:
bBloco = { || max(10,8) }
cSTRING_BLOCK:=valtoprg(bBloco)


Pablo essa é para ti...
Imagem

Codeblock para String, tem como? - Harbour

MensagemEnviado: 09 Mai 2011 22:02
por Pablo César
kkkkkk, essa da pá de ouro foi poruqe desenterrei o tópico ? Ahhh sei lá, primeiro pesquisei pra ver se tinha algo sobre o tema...
Sei lá o que você fez ai, mas fiz um teste rapido aqui com uma função do clipper mesmo e me mostrou um monte de CHR()
Tem certeza que fizestes em Clipper ? Acho que não, eihn ?

Vou deixar pra amanhã, eu queria ver os codesblocks mas não está dando... acho que em xHarbour deve funcionar direitinho, ja ví mensagens na internet falando que não funciona corretamente em Harbour...

Codeblock para String, tem como? - Harbour

MensagemEnviado: 09 Mai 2011 22:20
por asimoes
Aos Mestres,

Isto é possível?

bBloco = "{ || Funcao() }"
MsgInfo(HB_ValToStr(bBloco))
EVAL(&bbloco)

Função ValToPrg
FUNCTION ValToPrg( xValue )
   LOCAL cType := ValType( xValue )

   DO CASE
   CASE cType == "C"

      xValue := StrTran( xValue, Chr(0), '"+Chr(0)+"' )
      xValue := StrTran( xValue, Chr(9), '"+Chr(9)+"' )
      xValue := StrTran( xValue, Chr(10), '"+Chr(10)+"' )
      xValue := StrTran( xValue, Chr(13), '"+Chr(13)+"' )
      xValue := StrTran( xValue, Chr(26), '"+Chr(26)+"' )

      RETURN '"' + xValue + '"'

   CASE cType == "N" ; RETURN LTrim( Str( xValue ) )
   CASE cType == "D" ; RETURN 'HB_SToD("' + DToS( xValue ) + '")'
   CASE cType == "L" ; RETURN iif( xValue, ".T.", ".F." )
   CASE cType == "O" ; RETURN xValue:className() + " Object"
   CASE cType == "U" ; RETURN "NIL"
   CASE cType == "B" ; RETURN '{||...}'
   CASE cType == "A" ; RETURN '{.[' + LTrim( Str( Len( xValue ) ) ) + '].}'
   CASE cType == "M" ; RETURN 'M:"' + xValue + '"'
   ENDCASE

   RETURN ""

Codeblock para String, tem como? - Harbour

MensagemEnviado: 10 Mai 2011 14:15
por Pablo César
Isto é possível?

bBloco = "{ || Funcao() }"
MsgInfo(HB_ValToStr(bBloco))
EVAL(&bbloco)
Se inserir um MsgInfo(ValType(bBloco)) depois da linha bBloco = "{ || Funcao() }" verá que na tela irá aparecer "C" que é do tipo caracter, não do tipo "B" bloco. ATé agora sem solução.

Codeblock para String, tem como? - Harbour

MensagemEnviado: 10 Mai 2011 15:04
por sygecom
Eu não disse que compilei em Clipper, eu disse que fiz um teste usando uma função do CLIPPER olhe o exemplo que postei. Só que uso xHarbour, mas no Harbour deve dar certo do mesmo jeito é tudo a mesma M.....

Codeblock para String, tem como? - Harbour

MensagemEnviado: 07 Mai 2014 19:40
por Pablo César
Nossa gente ! Vim aqui correndo para compartilhar a minha mais recente conquista. Justamente o que eu vinha precisando e estudando há muito tempo este caso. Vim em consideração a muitos amigos daqui, principalmente a Rossine que é muito atenciosa comigo.

Por falar em Rossine, você é mulher não é Rossine ? Desculpe, senão for... pois o seu nick pode ser um sobrenome... rs Você é muito inteligente e obrigado pela atenção e de muitos aqui que são verdadeiros amigos.

Tenho muita consideração com esta comunidade, que deu-me muitas alegrias porque a benevolência do benemérito Paulo César Toledo, grande jóia do nosso querido Brasil e da nossa comunidade xBase, ele é inigualável. Muito sucesso para ti Toledo, você é o cara !

Então voltando ao assunto...

Neste tópico (desculpe estar em espanhol) mas acho que dá pra entender. Explico as minhas razões deste meu novo projeto que espero que ajude a todo que utilizam arquivos fmg.

A ideia é recuperar o conteúdo de um codeblock. Mas a jogada está, que antes de formar o codeblock seja feito como string. Neste no meu caso, eu tive que ler o arquivo fmg linha a linha (o que é caracterizado como string) e antes de ser lido pelo hb_compileFromBuf e ser transformado em atribuição de variável/array a função que continha eu havia colocado entre aspas. Depois foi só colocar := Eval(xVal) que retorna string. E se depois for necessário (é claro que sempre é), utilizar o codeblock, daí é só utilizar o macro para executá-la como comando.

Um grande abraço aqueles que sempre são dispostos a ajudar as pessoas. :)

Codeblock para String, tem como? - Harbour

MensagemEnviado: 08 Mai 2014 02:57
por rossine
Olá pablo,

Abaixo tem uma solução paleativa para retornar codeblock em string. Veja se serve para você ok ?

#Translate CBNew(<b>)    => { <b>, <(b)> }
#Translate CBEval(<b>)   => eval( <b>\[1\] )
#Translate CBString(<b>) => <b>\[2\]

*************
function MAIN
*************

local bCod1 := CBNew( { || MINHA_FUNC("Teste") } )
local bCod2 := CBNew( { || MINHA_FUNC(12) } )
local bCod3 := CBNew( { || MINHA_FUNC("Teste") } )
local bCod4 := CBNew( { || nCtd += 1, npar2 -=1, npar3 +=10 } )

private nCtd := 0, npar2 := 0, npar3 := 0

cls

? "-CBEval-"
? CBEval( bCod1 )
? "---"
? CBEval( bCod2 )
? "---"
? CBEval( bCod3 )
? "---"
? CBEval( bCod4 )
? "---"

? "-CBString-"
? CBString(  bCod1 )
? "---"
? CBString(  bCod2 )
? "---"
? CBString(  bCod3 )
? "---"
? CBString(  bCod4 )
? "---"

return NIL

****************
function MsgInfo( cMsg )
****************

? cMsg

return NIL

*******************
function MINHA_FUNC( uDesc )
*******************

? valtype(uDesc), uDesc

return uDesc


Por falar em Rossine, você é mulher não é Rossine ? Desculpe, senão for... pois o seu nick pode ser um sobrenome... rs Você é muito inteligente e obrigado pela atenção e de muitos aqui que são verdadeiros amigos.


Não amiguinho, joy soy macho heheheh. Me parece que no sul do brasil tem muita mulher com este nome/sobrenome e as vezes o pessoal confundi mesmo. hehehe No problem...

Precisando estamos aqui,

Abraço,

Rossine.

Codeblock para String, tem como? - Harbour

MensagemEnviado: 08 Mai 2014 10:11
por Pablo César
Exemplo perfeito, Rossine !

Ficou muito claro que fazer pelo translate fica muito mais simplificado e funcional.

Valeu pelo seu exemplo, muito didático.

rossine escreveu:Não amiguinho, joy soy macho heheheh
Caramba ! Foi mals então, ainda bem que pedi desculpas antecipadamente... Imagem

E muito obrigado pela sua contribuição !

:{ :)Pos

P.S. Ahhh se não se importarem, irei postar o seu exemplo lá no fórum HMG também.