Scala borrows Java String methods like toUpperCase/toLowerCase.
However, the way it does so is not very consistent:
Scala on JVM stick close to Java semantics, thus:
toUpperCase() is locale-sensitive and sticks to default locale (giving you infamous i → İ problem in Turkish locale)
to avoid that and keep locale-insensitive (en_US / C-like) process, you need to specifically do toUpperCase(Locale.ROOT)
Scala.JS does not implement a concept of Locale, thus:
toUpperCase() works in locale-insensitive manner
toUpperCase(Locale locale) method is effectively not available in ScalaJS
How do I implement locale-insensitive case conversion that will work in Scala on both JVM/JS?
I can think of several ways, all of them as ugly:
Method 1: My own implementation
Implement my own toUpperCase for specifically 26 ASCII characters of English alphabet.
Method 1.1: My own implementation using Scala chars
Basically the same, but at least reuse Scala toUpper to convert individual chars.
Method 2: Interface
Implement something like
trait CaseChangeOps {
def toUpperCase(s: String): String
}
object Main {
var caseChanger: CaseChanger
}
// whenever I want to use it, do it like that:
Main.caseChanger.toUpperCase("like this") // => "LIKE THIS"
in shared code, and then in JS have:
object CaseChangerJs {
def toUpperCase(s: String): String = s.toUpperCase
}
object MainJs {
Main.caseChanger = CaseChangerJs
}
... and in JVM:
object CaseChangerJvm {
def toUpperCase(s: String): String = s.toUpperCase(Locale.ROOT)
}
object MainJvm {
Main.caseChanger = CaseChangerJvm
}
Method 3: bring external scala-java-locales
There is a distinct 3rd party library scala-java-locales, which is listed as ScalaJS-compatible, and can be used to augument ScalaJS.
Looks like a massive overkill, though, as I literally only need locale-insensitive case conversions, not the whole thing for all possible locales.
Any better ideas?
The standard approach is close to your method 2, but much simpler. In shared code you just call
Platform.toUpperLocaleInsensitive(string)
which has different implementations on JVM and JS:
// JVM
object Platform {
def toUpperLocaleInsensitive(s: String) = s.toUpperCase(Locale.ROOT)
// other methods with different implementations
}
// JS
object Platform {
def toUpperLocaleInsensitive(s: String) = s.toUpperCase()
// other methods with different implementations
}
See the description of a similar case in Hands-on Scala.js.
This works because shared code doesn't need to compile by itself, only together with platform-specific code.
Related
In Cucumber 7.4.1+ TypeRegistry is deprecated in favour of annotations.
Indeed, as of today, I have never used anything but #ParameterType to define my ParameterTypes. Searching for alternatives, TypeRegistry is the only one I have found - but if it is "on the way out", of course I'd rather not start using it now.
Given a construct like this I cannot use annotations because those cannot take static parameters:
enum SpecialDate implements Supplier<Date> {
TODAY { #Override public Date get() { return Date(); } },
// YESTERDAY, etc.
;
static String typeSafeRegEx() {
return Arrays.stream(Zeitpunkt.values())
.map(SpecialDate::specName)
.collect(Collectors.joining("|"));
}
static SpecialDate from(final String specName) {
return valueOf(StringUtils.upperCase(specName));
}
String specName() {
return StringUtils.capitalize(StringUtils.lowerCase(this.name()));
}
}
public class ParameterTypes {
// does not compile: "Attribute value must be constant"
#ParameterType("(" + SpecialDate.typeSafeRegEx() + ")")
public Date specialDate(final String specName) {
return SpecialDate.from(specName).get();
}
}
A so-specified regEx is nice, because it will only match values guaranteed to be mappable, so I need no additional error handling code beyond Cucumber's own. The list of allowed values is also maintenance-free (compared to a "classic" switch which would silently grow incorrect when adding new values).
The alternative would be to use an unsafe switch + default: throw, strictly worse because it has to be maintained manually.
(Or, I guess, to just valueOf whatever + wrap into a more specific exception, when it eventually fails.)
To me, Cucumber's native UndefinedStepException appears to be the best outcome on a mismatch, because everyone familiar with Cucumber will immediately recognise it, unlike a project-specific one.
I see that e.g. the ParameterType class is not deprecated but cannot seem to find information how to use it without TypeRegistry.
FWIW:
Updating the libraries or Java would not be an issue. (But downgrading is sadly not viable.)
Business Specialists want to write examples like [Today], [Today + 1], [Yesterday - 3], etc. If this can be realised more elegantly using a different approach, X/Y answers would also be welcome.
An example step looks like this:
And I enter into the field 'Start of Implementation' the <begin>
Examples:
| begin
| [Today]
| [Today + 1]
I'm relying on an old Java API that kinda sucks and loves to throw null pointer exceptions when data is missing. I want to create a subclass that has option type accessors but preserves the old accessors until I decide I need to create safe accessors for them. Is there a good way to create a subclass from a copy of the original object? I'd like to achieve something like the following:
SafeIssue extends Issue {
def safeMethod: Option[Value] = { //... }
}
val issue = oldapi.getIssue()
val safeIssue = SafeIssue(issue)
//Preserves issue's methods and data if I need them
val unsafeVal = safeIssue.unsafeMethod
val maybeVal = safeIssue.safeMethod
Why not try an implicit conversion instead? This works better with Java APIs that like to create their own objects. So you would
class SafeIssue(issue: Issue) {
def original = issue
def safeFoo = Option(issue.foo)
// ... You must write any of these you need
}
implicit def make_issues_safe(issue: Issue) = new SafeIssue(issue)
Then you can--as long as you've supplied the method--write things like
val yay = Issue.myStaticFactoryMethodThing.safeFoo.map(x => pleaseNoNull(x))
(You can then decide whether you want to carry SafeIssue or Issue around in your code, and you can always get back the Issue from SafeIssue with the exposed original method (or you could make the issue parameter a val.)
I have seen the at (#) sign in Groovy files and I don't know if it's a Groovy or Java thing. I have tried to search on Google, Bing, and DuckDuckGo for the mystery at sign, but I haven't found anything. Can anyone please give me a resource to know more about what this operator does?
It's a Java annotation. Read more at that link.
As well as being a sign for an annotation, it's the Groovy Field operator
In Groovy, calling object.field calls the getField method (if one exists). If you actually want a direct reference to the field itself, you use #, ie:
class Test {
String name = 'tim'
String getName() {
"Name: $name"
}
}
def t = new Test()
println t.name // prints "Name: tim"
println t.#name // prints "tim"
'#' is an annotations in java/ Groovy look at the demo :Example with code
Java 5 and above supports the use of annotations to include metadata within programs. Groovy 1.1 and above also supports such annotations.
Annotations are used to provide information to tools and libraries.
They allow a declarative style of providing metadata information and allow it to be stored directly in the source code.
Such information would need to otherwise be provided using non-declarative means or using external files.
It can also be used to access attributes when parsing XML using Groovy's XmlSlurper:
def xml = '''<results><result index="1"/></results>'''
def results = new XmlSlurper().parseText(xml)
def index = results.result[0].#index.text() // prints "1"
http://groovy.codehaus.org/Reading+XML+using+Groovy's+XmlSlurper
The situation seems to be abnormal, but I was asked to build serializer that will parse an object into string by concatenating results of "get" methods. The values should appear in the same order as their "get" equivalent is declared in source code file.
So, for example, we have
Class testBean1{
public String getValue1(){
return "value1";
}
public String getValue2(){
return "value2";
}
}
The result should be:
"value1 - value2"
An not
"value2 - value1"
It can't be done with Class object according to the documentation. But I wonder if I can find this information in "*.class" file or is it lost? If such data exists, maybe, someone knows a ready to use tool for that purpose? If such information can't be found, please, suggest the most professional way of achieving the goal. I thought about adding some kind of custom annotations to the getters of the class that should be serialized.
If you want that you have to parse the source code, not the byte code.
There are a number of libraries that parse a source file into a node tree, my favorite is the javaparser (hosted at code.google.com), which, in a slightly modified version, is also used by spring roo.
On the usage page you can find some samples. Basically you will want to use a Visitor that listens for MethodDefinitions.
Although reflection does not anymore (as of java 7 I think) give you the methods in the order in which they appear in the source code, the class file appears to still (as of Java 8) contain the methods in the order in which they appear in the source code.
So, you can parse the class file looking for method names and then sort the methods based on the file offset in which each method was found.
If you want to do it in a less hacky way you can use Javassist, which will give you the line number of each declared method, so you can sort methods by line number.
I don't think the information is retained.
JAXB, for example, has #XmlType(propOrder="field1, field2") where you define the order of the fields when they are serialized to xml. You can implemenet something similar
Edit: This works only on concrete classes (the class to inspect has its own .class file). I changed the code below to reflect this. Until diving deeper into the ClassFileAnalyzer library to work with classes directly instead of reading them from a temporary file this limitation exists.
Following approach works for me:
Download and import following libarary ClassFileAnalyzer
Add the following two static methods (Attention! getClussDump() needs a little modification for writing out the class file to a temporary file: I removed my code here because it's very special at this point):
public static String getClassDump(Class<?> c) throws Exception {
String classFileName = c.getSimpleName() + ".class";
URL resource = c.getResource(classFileName);
if (resource == null) {
throw new RuntimeException("Works only for concreate classes!");
}
String absolutePath = ...; // write to temp file and get absolute path
ClassFile classFile = new ClassFile(absolutePath);
classFile.parse();
Info infos = new Info(classFile, absolutePath);
StringBuffer infoBuffer = infos.getInfos();
return infoBuffer.toString();
}
public static <S extends List<Method>> S sortMethodsBySourceOrder(Class<?> c, S methods) throws Exception {
String classDump = getClassDump(c);
int index = classDump.indexOf("constant_pool_count:");
final String dump = classDump.substring(index);
Collections.sort(methods, new Comparator<Method>() {
public int compare(Method o1, Method o2) {
Integer i1 = Integer.valueOf(dump.indexOf(" " + o1.getName() + lineSeparator));
Integer i2 = Integer.valueOf(dump.indexOf(" " + o2.getName() + lineSeparator));
return i1.compareTo(i2);
}});
return methods;
}
Now you can call the sortMethodsBySourceOrder with any List of methods (because sorting arrays is not very comfortable) and you will get the list back sorted.
It works by looking at the class dumps constant pool which in turn can be determined by the library.
Greetz,
GHad
Write your custom annotation to store ordering data, then use Method.getAnnotation(Class annotationClass)
I inherited large monolithic body of OO Perl code that needs to be gradually converted to Java (per client request). I know both languages but am rusty on my Perl skills. Are there any tools (Eclipse plugins?) that you folks can recommend to ease the pain?
Does OO code use Moose? If yes, it is possible to convert class declarations automatically using introspection.
To gradually convert Perl to Java, you can include Java code into Perl program with Inline::Java.
There is Perl on JVM project, maybe it can be used to compile Perl to Java?
I'd say PLEAC is one of the greatest resources.
The inccode.com allows you to automatically convert the perl code to java code. Nevertheless the conversion of perl variables is slightly tricky due to dynamic typing in perl. The scalar variable in perl can contain the reference to any type and the real referenced type is known when the code is executed.
Translator uses VarBox class for encapsulating all predefined types: ref(HASH), ref(ARRAY) and BoxModule for encapsulating the reference to Perl Modules.
The example show perl script which call two modules to print “hello world”. The module LibConsole is instantiated in script and the module LibPrinter is accessed by calling the method in LibConsole.
#!/usr/bin/perl
use strict;
use test::LibPrinter;
use test::LibConsole;
hello_on_console( "hello world");
hello_on_printer( "hello world");
sub get_console
{
my $console = test::LibConsole->new();
return $console;
}
sub get_printer
{
##cast(module="test::LibPrinter")
my $printer = get_console()->get_printer();
return $printer;
}
sub hello_on_console
{
my ($hello) = #_;
my $console = get_console();
$console->output ($hello);
}
sub hello_on_printer
{
my ($hello) = #_;
my $printer= get_printer();
$printer->output ($hello);
}
Translator must now the types of both modules and while perl don’t define specific operators for declaring the object there’s an assumption that method named “new” return the reference to module. When the method which return reference to module is named otherwise the annotation cast(module=”{class}”) can be used to inform translator about the type of the module.
The identified type of the variable will be propagate because the translator control the conformity of types in assignments.
public class hello extends CRoutineProcess implements IInProcess
{
VarBox call ()
{
hello_on_console("hello world");
return hello_on_printer("hello world");
}
BoxModule<LibConsole> get_console ()
{
BoxModule<LibConsole> varConsole = new BoxModule<LibConsole>(LibConsole.apply());
return varConsole;
}
BoxModule<test.LibPrinter> get_printer ()
{
BoxModule<LibPrinter> varPrinter = new BoxModule<LibPrinter>(get_console().getModule().get_printer());
return varPrinter;
}
VarBox hello_on_console (VarBox varHello)
{
BoxModule<LibConsole> varConsole = new BoxModule<LibConsole>(get_console());
return varConsole.getModule().output(varHello);
}
VarBox hello_on_printer (VarBox varHello)
{
BoxModule<LibPrinter> varPrinter = new BoxModule<LibPrinter>(get_printer());
return varPrinter.getModule().output(varHello);
}
}
The translated code requires runtime library to be executed.