From docs:
Procedure blocks enforce variable scoping: methods cannot see variables defined by their caller. New applications use procedure blocks; non-procedure blocks exist for backwards compatibility.
- Log in to post comments
From docs:
Procedure blocks enforce variable scoping: methods cannot see variables defined by their caller. New applications use procedure blocks; non-procedure blocks exist for backwards compatibility.
I need to run my code one per job start, that's why OnInit does not help.
OnProductionStart is closer, however it runs in a parent job and not in the Business Process job itself.
Still, thank you for a very throughout explanation.
For me the main acceptable case of foreach iteration is business objects - for example we receive array of results and must process them. In that case we, of course, must iterate over them, no way around it.
Everything static: constraints, enums, dictionaries, etc... should be (and usually could be) used without foreach iteration.
I agree that there are cases where we need to do something over each element of the collection.
But you said:
constants, static arrays in algorithms, e.g. arbitrary dictionaries
Which implies that foreach iteration is not desired here.
Anyways, in that case what does matter is size.
If you're sure that it would be less than $$$MaxStringLength then you can use $lb, otherwise use locals (which can be converted to ppg/globals easily).
TOP 100.
In EntityBrowser.API class set PAGESIZE parameter to 100 and compile the class.
1. Before we iterate over rows we need to determine column type, the example is about that.
Here's an example of what I'm talking about.
2. You want to avoid full scan as much as possible. Two techniques for that are:
And that determines the type of structure used.
If you don't know either you need to think about possible algorithm improvements.
It depends on a use case.
Consider the scenario of iterating over the result set. You need to do two things:
To solve the first one (and assuming we get values by position number) the most efficient solution would be iterating over metadata once and building something like this:
set columns = $lb("int", "bool", "str", ...)Then in each row we can easily get datatype by:
for i=1:1:colCount {
set dataType = $lg(columns, i)
set value = rs.Get(i)
}Now for a second part - value translation, locals are great here. We prep our translator:
set local(1) = "a"
set local("hi") = "world"and replace the value if needed
set:$data(local(value), newValue) value = newValue
Ok.
Parameter is about 6x faster btw:
ClassMethod GetMonthList1() As %List
{
Quit $Listfromstring("January,February,March,April,May,June,July,August,September,October,November,December")
}
ClassMethod GetMonthList2() As %List [ CodeMode = expression ]
{
$Listfromstring("January,February,March,April,May,June,July,August,September,October,November,December")
}
ClassMethod GetMonthList3() As %List [ CodeMode = expression ]
{
$lb("January","February","March","April","May","June","July","August","September","October","November","December")
}
Parameter GetMonthList = {$lb("January","February","March","April","May","June","July","August","September","October","November","December")};
ClassMethod Time2()
{
for method = 1:1:3 {
set start = $zh
for i=1:1:10000 {
set result = $classmethod(,"GetMonthList" _ method)
}
set end = $zh
write $$$FormatText("Method: %1, time: %2", "GetMonthList" _ method, end - start),!
}
set start = $zh
for i=1:1:10000 {
set result = ..#GetMonthList
}
set end = $zh
write $$$FormatText("Parameter, time: %1", end - start),!
}Results
Method: GetMonthList1, time: .007255
Method: GetMonthList2, time: .006717
Method: GetMonthList3, time: .003878
Parameter, time: .000605Why
ClassMethod GetMonthList1() As %List
{
Quit $Listfromstring("January,February,March,April,May,June,July,August,September,October,November,December")
}instead of
ClassMethod GetMonthList3() As %List
{
Quit $lb("January","February","March","April","May","June","July","August","September","October","November","December")
}
What doesn't work in 2019.0?
Also do you mean 2019.1.0?
Not yet.
Starting from 2019.2 there's a %JSON.Adapter, for automatic bidirectional JSON<>Object transformation.
For example
Parameter SETTINGS = "XSLТ:Basic:selector?context={isc.util.EnsSearchUtils/GetXDatas?class=util.XDatas}"And inside the method you would get
zw pParms
pParms("class") = "util.XDatas"Here's sample code
ClassMethod GetXDatas(Output pCaption As %String, Output pTopResults, Output pResults, ByRef pParms As %String, pSearchKey As %String = "") As %Status
{
Set tStatus = $$$OK
Kill pResults, pTopResults
Set pCaption = $$$Text("My Localized Caption")
Set tClass = $get(pParms("class"))
If tClass '= "" {
Set tClassObj = ##class(%Dictionary.CompiledClass).%OpenId(tClass)
For i=1:1:tClassObj.XDatas.Count() {
Set tName = tClassObj.XDatas.GetAt(i).Name
Set pResults($i(pResults)) = tName
Set:tName["import" pTopResults($i(pTopResults)) = tName
}
}
Quit tStatus
}
}
It would search for all XDatas in class parameter (utils.XDatas in our case) and show those of them containing Import word at the top. Caption would be "My Localized Caption" but you can add localizations to it.
So, does it work for you?
Seems correct.
Right.
You're right, I need to change $replace with Ш to $replace with Щ. Ш is replaced in $translate anyway
ClassMethod convertRussionToEnglish4(russian = "привет") As %String [ CodeMode = expression ]
{
$tr($zcvt($replace($replace($tr(russian, "абвгдезийклмнопрстуфхыэАБВГДЕЗИЙКЛМНОПРСТУФХЫЭЖЦЧШЮЯжцчшюяьЬъЪ", "abvgdeziyklmnoprstufhyeABVGDEZIYKLMNOPRSTUFHYE婨味䍨卨奵奡穨瑳捨獨祵祡"),"щ","shch"),"Щ","Shch"),"O","UnicodeBig"),$c(0))
}Interesting. Starting from 2019.2 there's a %JSON.Adapter, check it out when you update.
Also is there any particular reason you use these calls:
Set pObject=$Xecute("() Quit ##class("_pObjectName_").%New()")Instead of this:
Set pObject = $classmethod(pObjectName, "%New")?
Here's my new one-liner. Now 6 times faster.
ClassMethod convertRussionToEnglish4(russian = "привет") As %String [ CodeMode = expression ]
{
$tr($zcvt($replace($replace($tr(russian, "абвгдезийклмнопрстуфхыэАБВГДЕЗИЙКЛМНОПРСТУФХЫЭЖЦЧШЮЯжцчшюяьЬъЪ", "abvgdeziyklmnoprstufhyeABVGDEZIYKLMNOPRSTUFHYE婨味䍨卨奵奡穨瑳捨獨祵祡"),"щ","shch"),"Ш","Sh"),"O","UnicodeBig"),$c(0))
}Here's tests:
do ##class(Test.Cyr).Time()
Method: convertRussionToEnglish1, time: .009022 <- original
Method: convertRussionToEnglish2, time: .000689 <- my first idea
Method: convertRussionToEnglish3, time: .000417 <- Evgeny
Method: convertRussionToEnglish4, time: .000072 <- this version
Method: convertRussionToEnglish5, time: .000124 <- JonCompete code
Class Test.Cyr
{
/// do ##class(Test.Cyr).Time()
ClassMethod Time()
{
set words = $lb("Дорогие", "друзья", "начало", "повседневной", "работы", "по", "формированию", "позиции", "позволяет", "оценить", "значение", "ключевых", "компонентов", "планируемого", "обновления", "Соображения", "высшего", "порядка", "а", "также", "курс", "на", "социальноориентированный", "национальный", "проект", "играет", "важную", "роль", "в", "формировании", "всесторонне", "сбалансированных", "нововведений", "Таким", "образом", "сложившаяся", "структура", "организации", "способствует", "подготовке", "и", "реализации", "позиций", "занимаемых", "участниками", "в", "отношении", "поставленных", "задач")
for method = 1:1:5 {
set start = $zh
for i=1:1:$ll(words) {
set result = $classmethod(,"convertRussionToEnglish" _ method , $lg(words, i))
}
set end = $zh
write $$$FormatText("Method: %1, time: %2", "convertRussionToEnglish" _ method, end - start),!
}
}
ClassMethod getDict(Output dict)
{
kill dict
set dict("а")="a"
set dict("б")="b"
set dict("в")="v"
set dict("г")="g"
set dict("д")="d"
set dict("е")="e"
set dict("ж")="zh"
set dict("з")="z"
set dict("и")="i"
set dict("й")="y"
set dict("к")="k"
set dict("л")="l"
set dict("м")="m"
set dict("н")="n"
set dict("о")="o"
set dict("п")="p"
set dict("р")="r"
set dict("с")="s"
set dict("т")="t"
set dict("у")="u"
set dict("ф")="f"
set dict("х")="kh"
set dict("ц")="ts"
set dict("ч")="ch"
set dict("ш")="sh"
set dict("щ")="shch"
set dict("ъ")=""
set dict("ы")="y"
set dict("ь")=""
set dict("э")="e"
set dict("ю")="yu"
set dict("я")="ya"
}
/// w ##class(Test.Cyr).convertRussionToEnglish2()
ClassMethod convertRussionToEnglish2(word As %String = "Привет")
{
do ..getDict(.dict)
set out = ""
for i=1:1:$l(word) {
set letter = $e(word, i)
set letterL = $zcvt(letter, "l")
set outLetter = dict(letterL)
set:letter'=letterL outLetter = $zcvt(outLetter, "U")
set out = out _ outLetter
}
quit out
}
ClassMethod convertRussionToEnglish3(russian = "привет") As %String
{
set rus="абвгдезийклмнопрстуфхыэАБВГДЕЗИЙКЛМНОПРСТУФХЫЭьЬъЪ"
set eng="abvgdeziyklmnoprstufhyeABVGDEZIYKLMNOPRSTUFHYE"
set rus("ж")="zh"
set rus("ц")="ts"
set rus("ч")="ch"
set rus("ш")="sh"
set rus("щ")="shch"
set rus("ю")="yu"
set rus("я")="ya"
set rus("Ж")="Zh"
set rus("Ц")="Ts"
set rus("Ч")="Ch"
set rus("Ш")="Sh"
set rus("Щ")="Shch"
set rus("Ю")="Yu"
set rus("Я")="Ya"
set english=$tr(russian,rus,eng)
set wow=$O(rus(""))
while wow'="" {
set english=$Replace(english,wow,rus(wow))
set wow=$O(rus(wow))
}
return english
}
ClassMethod convertRussionToEnglish4(russian = "привет") As %String [ CodeMode = expression ]
{
$tr($zcvt($replace($replace($tr(russian, "абвгдезийклмнопрстуфхыэАБВГДЕЗИЙКЛМНОПРСТУФХЫЭЖЦЧШЮЯжцчшюяьЬъЪ", "abvgdeziyklmnoprstufhyeABVGDEZIYKLMNOPRSTUFHYE婨味䍨卨奵奡穨瑳捨獨祵祡"),"щ","shch"),"Ш","Sh"),"O","UnicodeBig"),$c(0))
}
ClassMethod convertRussionToEnglish1(word As %String)
{
//add array of transliteration system
Set convertArray = $LB(
$LB("а","a"),$LB("б","b"),$LB("в","v"),$LB("г","g"),$LB("д","d"),$LB("е","e"),$LB("ё","e"),$LB("ж","zh"),$LB("з","z"),
$LB("и","i"),$LB("й","y"),$LB("к","k"),$LB("л","l"),$LB("м","m"),$LB("н","n"),$LB("о","o"),$LB("п","p"),
$LB("р","r"),$LB("с","s"),$LB("т","t"),$LB("у","u"),$LB("ф","f"),$LB("х","kh"),$LB("ц","ts"),$LB("ч","ch"),
$LB("ш","sh"),$LB("щ","shch"),$LB("ы","y"),$LB("э","e"),$LB("ю","yu"),$LB("я","ya"),$LB("ъ",""),$LB("ь",""),
$LB("А","A"),$LB("Б","B"),$LB("В","V"),$LB("Г","G"),$LB("Д","D"),$LB("Е","E"),$LB("Ё","E"),$LB("Ж","ZH"),$LB("З","Z"),
$LB("И","I"),$LB("Й","Y"),$LB("К","K"),$LB("Л","L"),$LB("М","M"),$LB("Н","N"),$LB("О","O"),$LB("П","P"),
$LB("Р","R"),$LB("С","S"),$LB("Т","T"),$LB("У","U"),$LB("Ф","F"),$LB("Х","KH"),$LB("Ц","TS"),$LB("Ч","CH"),
$LB("Ш","SH"),$LB("Щ","SHCH"),$LB("Ы","Y"),$LB("Э","E"),$LB("Ю","YU"),$LB("Я","YA"),$LB("Ъ",""),$LB("Ь","")
)
//word Example
Set wordToConvert = "Пример для Кода"
Set wordToConvertLength = $L(wordToConvert)
Set cnt=$ListLength(convertArray)
Set latinWord = ""
//and with cycle get each letter and parse in transliteration array
for i=1:1:wordToConvertLength {
Set cyrillicWord = $E(wordToConvert,i)
for j=1:1:cnt {
Set codes=$ListGet(convertArray,j)
Set cyrillicLetter=$ListGet(codes,1)
Set latinLetter=$ListGet(codes,2)
if cyrillicLetter=cyrillicWord {
Set cyrillicWord = latinLetter
}
}
Set latinWord = latinWord_cyrillicWord
}
//Get result of convert
Quit latinWord
}
ClassMethod convertRussionToEnglish5(russian = "привет") As %String
{
s koi8=$zcvt(russian,"O","KOI8R")
s ascii=""
f i=1:1:$l(koi8) s ascii=ascii_$c($zb($a(koi8,i),127,1))
q ascii
}
}Less searching all around:
ClassMethod getDict(Output dict)
{
kill dict
set dict("а")="a"
set dict("б")="b"
set dict("в")="v"
set dict("г")="g"
set dict("д")="d"
set dict("е")="e"
set dict("ж")="zh"
set dict("з")="z"
set dict("и")="i"
set dict("й")="y"
set dict("к")="k"
set dict("л")="l"
set dict("м")="m"
set dict("н")="n"
set dict("о")="o"
set dict("п")="p"
set dict("р")="r"
set dict("с")="s"
set dict("т")="t"
set dict("у")="u"
set dict("ф")="f"
set dict("х")="kh"
set dict("ц")="ts"
set dict("ч")="ch"
set dict("ш")="sh"
set dict("щ")="shch"
set dict("ъ")=""
set dict("ы")="y"
set dict("ь")=""
set dict("э")="e"
set dict("ю")="yu"
set dict("я")="ya"
}
/// w ##class(Test.Cyr).convertRussionToEnglish()
ClassMethod convertRussionToEnglish(word As %String = "Привет")
{
do ..getDict(.dict)
set out = ""
for i=1:1:$l(word) {
set letter = $e(word, i)
set letterL = $zcvt(letter, "l")
set outLetter = dict(letterL)
set:letter'=letterL outLetter = $zcvt(outLetter, "U")
set out = out _ outLetter
}
quit out
}What do you want to achieve?
Do you want to read or write excel files?
Studio -> Edit -> Find in Files?
Can containerized IAM work with non-containerized InterSystems IRIS?
Not that I know of.
If you're sure about MAXLEN it's better to specify it explicitly of course, but if you have no idea %VarString is a nice solution.
Use %VarString instead of %String - it has default length of 3 641 144 characters.