Reverse a string in KIBANA/painless - elasticsearch-painless

I'm not able to reverse a string in KIBANA/painless (section: scripted fields)
def foo = ('dlroW olleH');
return foo.reverse();
I expect the output of "Hello World", but KIBANA sais "No results found".
If i do a "return foo;" it works well - on every outputline "dlroW olleH" is shown.
Can anyone give me a hint, where the problem is?
EDIT: kibana 5.6, regexp for painless is disabled

.reverse() isn't a listed method to operate on a String object [1]; it's available to operate a StringBuffer object. [2]
You can make a StringBuffer and call reverse on it.
StringBuffer foo = new StringBuffer('dlroW olleH');
foo.reverse();
return foo.toString();

Related

How to use polymorphism to remove a switch statement which compares strings?

I am new to Ruby, so let me describe the context of my problem first:
I have a json as input which has the following key / value pair:
{
"service": "update"
}
The value has many different values for example: insert,delete etc.
Next there is a method x which handles the different requests:
def x(input)
case input[:service]
services = GenericService.new
when "update"
result = services.service(UpdateService.new,input)
when "insert"
result = services.service(InsertService.new,input)
when "delete"
result = services.service(DeleteService.new,input)
....
....
else
raise "Unknown service"
end
puts JSON.pretty_generate(result)
end
What is bothering me is that I still need to use a switch statement to check the String values (reminds me of 'instance of' ugh..). Is there a cleaner way (not need to use a switch)?
Finally I tried to search for an answer to my question and did not succeed, if however I missed it feel free to comment the related question.
Update: I was thinking to maybe cast the string to the related class name as follows: How do I create a class instance from a string name in ruby? and then call result = services.services(x.constantize.new,input) , then the class names ofcourse needs to match the input of the json.
You can try something like:
def x(input)
service_class_name = "#{input[:service].capitalize}Service"
service_class = Kernel.const_get(service_class_name)
service_class.new(input).process
end
In addition you might want to check if this is a valid Service class name at all.
I don't understand why you want to pass the service to GenericService this seems strange. let the service do it's job.
If you're trying to instatiate a class by it's name you're actually speaking about Reflection rather than Polymorphism.
In Ruby you can achieve this in this way:
byName = Object.const_get('YourClassName')
or if you are in a Rails app
byName= 'YourClassName'.constantize
Hope this helps
Just first thoughts, but you can do:
eval(services.service("#{input[:service].capitalize}Service.new, #{input})") if valid_service? input[:service]
def valid_service?
w%(delete update insert).include? input[:service]
end
As folks will no doubt shout, eval needs to be used with alot of care

What is my method returning here?

I have a question that I've already found the solution to (or perhaps it is just chance), but I'm hoping someone can explain why it works, and what Ruby is doing being the scenes here.
I'm doing something with fixed width output text and ANSI color codes. I don't want the escaped characters to count towards my length, so I wrote a little method for the String class to calculate the length excluding the color codes:
def length_minus_codes
color_codes = [ "\033[30m",
"\033[0m" ,
"\033[31m",
"\033[32m",
"\033[33m",
"\033[34m",
"\033[35m",
"\033[36m",
"\033[37m",
"\033[40m",
"\033[41m",
"\033[42m",
"\033[43m",
"\033[44m",
"\033[45m",
"\033[46m",
"\033[47m",
"\033[1m",
"\033[22m",
"\033[7m",
"\033[27m"]
#Create new variable to strip
stripped_self = self
#loop through color code array
for index in 0 ... color_codes.size
#strip color codes from string
stripped_self.gsub!(color_codes[index],"")
end
#return variance of self to stripped self to
#get length of string not including color codes
return self.length - (self.length - stripped_self.length)
end
end
I thought it was working fine, until I realized that after it was called, the string it was called on had the character codes stripped from it.
I tried a few things, before decided to change this:
stripped_self.gsub!(color_codes[index],"")
To this:
stripped_self = stripped_self.gsub(color_codes[index],"")
Now it is working fine.
What I don't understand is why? I understand the basic concept of in place methods (!) which I was using on the gsub, but it wasn't modifying self, but rather a variable that I set in the method, and second I only want to return the length of the string, not an actual string.
Can anyone explain what is happening here?
When you do
stripped_self = self
you are simply creating a new reference to the self string object, you are not creating a new string. So any in-place modifications (by gsub! in this case) will be reflected on the self object.
If you want to create a new object that is not a reference, you need to duplicate the object:
stripped_self = self.dup
Possibly a simpler solution here is just to use the non-bang version of gsub and save that to a variable. gsub! changes the receiver as bang methods often do, gsub will simply return a modified object safely without effecting the receiver.

After performing string.slice() return string with part removed

Im sure this is very obvious but I cant seem to get it work.
I have a Pathname instance and Im attempting to remove the first directory from it and then return the rest of the string, but because slice returns the part removed it seems there is no way of getting the smaller string back.
filepath = Pathname.new("this_folder_needs_to_go/another_folder/file.html")
filedir = filepath.to_s.slice("this_folder_needs_to_go/")
newfilepath = filedir
I would hope newfilepath would be another_folder/file.html but instead it just returns this_folder_needs_to_go/
So how on earth to I get the string that has had the part removed?
Using String#split:
"this_folder_needs_to_go/another_folder/file.html".split('/', 2)[1]
# => "another_folder/file.html"
You can also use .slice! instead of .slice if you're trying to modify your string
filepath = Pathname.new("this_folder_needs_to_go/another_folder/file.html")
filepath.to_s.slice!("this_folder_needs_to_go/")
puts filepath ==> "another_folder/file.html"
Though that will affect your filepath variable irreversibly.
#partition will also work in a similar manner to #split
filepath = Pathname.new("this_folder_needs_to_go/another_folder/file.html")
file_dir = filepath.partition("this_folder_needs_to_go/")[-1]
file_dir
#=> "another_folder/file.html"
#partition returns [head,sep,tail] so this will look like ["","this_folder_needs_to_go","/another_folder/file.html"] the [-1] says get the last element.

c# stringbuilder tostring double quote issue

I have an issue when converting a string from stringbuilder to string.
The issue is similar to this issue but slightly different:
This is my code simplified:
StringBuilder sb = new StringBuilder();
sb.Append("\"");
sb.Append("Hello World");
sb.Append("\"");
string test = sb.ToString();
Now in the debugger the sb value is:
"Hello World"
In the debugger the test string value is changed to:
\"Hello World\"
When returning the test string value back to the browser the velue is STILL escaped:
\"Hello World\"
I have tried using the string replace:
test = test.Replace("\"", "");
no luck, I tried appending the ASCII character instead of \" and I have also tried a different append
sb.Append('"');
All these with no luck. Can somebody maybe point me in the right direction of why I'm still getting the escape character and how to get rid of it.
Thanks and appreciate any input.
Ok it seems that in WCF the stringBuilder automatically adds escape quotes. This means you can not get away from that. Also I was going about this all wrong. I was trying to return a string where I was supposed to return a serialised JSON object.
I'm not seeing the behavior you describe. Escaping double quotes with the backslash should work. The following snippet of code
var sb = new StringBuilder();
sb.Append("Ed says, ");
sb.Append("\"");
sb.Append("Hello");
sb.Append("\"");
Console.WriteLine(sb.ToString());
foreach (char c in sb.ToString()) Console.Write(c + "-");
Console.ReadKey();
produces
Ed says, "Hello"
E-d- -s-a-y-s-,- -"-H-e-l-l-o-"-
If you are getting actual backslash characters in your final display of the string, that may be getting added by something after the StringBuilder and ToString code.
You can use a verbatim string literal "#" before the string, then enter the quotes twice. This removes the use to use escapes in the string sequence :)
StringBuilder sb = new StringBuilder();
sb.Append(#"""");
sb.Append("Hello World");
sb.Append(#"""");
string test = sb.ToString();
This question and answer thread kept on coming up when searching for the solution.
The confusion, for me, was that the Debugger escaping looks exactly the same as the JSON serializer behaviour that was being applied later when I returned the string to a client. So the code at the top of the thread (and my code) worked correctly.
Once I realised that, I converted the piece of code I was working on return an array (string[] in this case) and store that rather than the original string object. Later the JSONResult serializer then dealt with converting the array correctly.

how to read parameters from console to method in groovy?

I am new to groovy.I am reading values for 2 variables from console with below lines of code.
System.in.withReader {
println "Version: "
version = it.readLine()
println "Doc Type:"
Doc=it.readLine()
call getBillID(version,Doc)
}
getBillid method is as below,
def getBillID(int version,int doc)
{
allNodes.BillID.each {
theregularExpression=/\d+_\d+_\d+_\d_\d+_\d+_\d_${version}_${Doc}_\d+_\d+/
if(it != "" && it =~ theregularExpression) {
println "******" + it
}
}
}
now i want to use those variable values in my getBILLID method but i am getting error as
No signature of method: ReadXML.getBillID() is applicable for argument types: (java.lang.String, java.lang.String) values: [9, ]
where i went wrong.can any one tell me plz..
In addition to #Kalarani's answer, you could also do this:
System.in.withReader {
print "Version: "
int version = it.readLine() as int
print "Doc Type: "
int doc = it.readLine() as int
getBillID( version, doc )
}
As an aside; I would be careful with your capitalisation and variable names, ie: you have a variable called Doc with a capital letter. This is not the standard naming scheme, and you are best using all lowercase for variable names. You can see where it has got confused in the getBillID method. The parameter is called doc (all lowercase), but in the regular expression you reference ${Doc} (uppercase again).
This sort of thing is going to end up causing you a world of pain and bugs that might take you longer to find
Where is the getBillId() method defined? and what is the signature of the method? It would help understanding your problem if you could post that.

Resources