Renaming a .scala file in Scala IDE does not rename the class - eclipse

When I rename a .scala file via Eclipse the class name itself is not renamed.
Is this expected behaviour? It does not seem to break anything.
I expect it to be renamed, coming from a Java background the filename/class name must equal each other.

correspondence between class name and file name is not required in scala.
You can (and usually do) define multiple types in each scala file.
The compiler will attempt to create a different .class file for each public type with the file name corresponding to the type name, for interoperability with java (for complex or nested types that don't have a direct correspondence in java, scalac will produce .class files with strange/mangled names...)
A few notes on why this correspondence is not enforced (probably not a complete list, but just to give you an idea):
it would be wasteful, given scala's terseness. case class Foo(foo:String) corresponds to a complete and somewhat sophisticated java class, but having it in its own file seems wasteful...
it would decrease code readability. Sometimes you define a hierarchy of case classes that correspond (for instance) to various messages you send to an actor. Having them together underlines their intent.
often it would be pointless. A relatively simple definition in scala, like trait Fooer {def foo="foo"} may be translated to various java-like types, that implement the "interface with a default implementation" nature of a trait. This gets worse for nested object/classes/types allowed by scala's syntax and used in some common scala patterns.
there are Scala semantics (sealed traits in particular) that actually require having multiple classes defined in a single file (credit to #DaveGriffith 's comment below)

In scala a .scala file can contain many (public) classes or packages.

The file name in scala does not have to match any of the class names in the file. You can have as many classes as you want in a scala file. The package structure also does not have to match the folder structure, although it is recommended to to be aligned.

Related

Why case class and object with different names appear in same scala file? [duplicate]

I've recently started programming in Scala, coming from Python and Java I was wondering what the correct way or the accepted way is when defining objects/classes in Scala. Scala supports, just like python, to add several class or object definitions in a single file.
So purely from an accepted structure perspective, does every object need to be defined in its own file or are you allowed to choose this yourself?
There is a chapter in the official Scala Style Guide on this. It's pretty clear in itself, but I'll just leave some quotes here.
The core idea is:
As a rule, files should contain a single logical compilation unit. By “logical” I mean a class, trait or object.
There is, of course, an exception for companion objects:
One exception to this guideline is for classes or traits which have companion objects. Companion objects should be grouped with their corresponding class or trait in the same file.
There is also the fact that sealed only works within the same file.
Despite what was said above, there are some important situations which warrant the inclusion of multiple compilation units within a single file. One common example is that of a sealed trait and several sub-classes. Because of the nature of sealed superclasses (and traits), all subtypes must be included in the same file.
Most of the time, case classes are just simple data containers and can be grouped together.
Another case is when multiple classes logically form a single, cohesive group, sharing concepts to the point where maintenance is greatly served by containing them within a single file.
Finally, there is a naming convention for exempted multi-unit Scala files:
All multi-unit files should be given camelCase names with a lower-case first letter.
So: put your Scala classes and objects in separate files, unless they fall into one of the three mentioned exceptions.
In Scala, it is perfectly valid to have multiple classes within a single file AS LONG AS they are tightly related.
But not all languages encourage this convention, and I think it is worth considering the reason.
I personally dislike it when people put multiple classes into a single file because it makes it harder to find a class definition. This is magnified in code reviews where I want to be able to review code as quickly as possible without digging around.
Cons
Code reviews require me to do more searching to find a class
I don't like having to grep to find a file
A consistent naming convention allows me to use my text editor or IDE tools to quickly open a file by the class name
Pros
As Jesper pointed out, certain scenarios require it
Support classes/traits are kept hidden to minimize file structure "noise"
Sometimes you have to put several traits, classes or objects in one source file, particularly when you are using sealed traits. A sealed trait can only be extended inside the same source file.

Package object for one-liner Scala classes

This is more of a design and readability/maintainability question rather than a technical one.
Sometimes in Scala, you get these one liner classes (often case classes), which are typically used to hold data. They're very synonymous with Java beans, but with constructor parameters actually being val members, no need for setter methods due to immutability, and no need for toString due to the nice feature of case classes, you end up with just one line consisting of constructor parameters.
I find it wasteful to put these one-liners in a separate Scala file, and I hate to put them with other more meaty Scala classes because it starts to become confusing (even in IntelliJ IDEA it starts to pollute the project source tree).
I started a new habit of putting these single liners in the Package Object package.scala file of that package. Is there any disadvantage to this from a maintainability point of view? I am just putting them there for lack of a better place. Is there any better approach?
I don't think there is a disadvantage in that, but also I don't see an immediate advantage or reason to do so.
You may have a look at this question. Basically, if you use the -Xlint compiler flag, you will be told that you should not put classes into a package object.
If you want to have several classes together because of their one-line nature, you can put them still together in one file, it doesn't have to be a package object. E.g.
// utils.scala
package foo
case class FooUtil()
case class BarUtil()
Instead of package object foo { case class FooUtil() ... }

Create class attributes dynamically in Scala

Is it possible to create a class (or add attributes to a class) dynamically, e.g. load field names and types from external file in Scala?
this is follow-up on Representing nested structures in scala
It is possible to achieve this with macros, and there are two techniques for that with a different set of trade-offs. Refer to our joint talk with Travis Brown for more information and a link to an example implementation: https://github.com/travisbrown/type-provider-examples/blob/master/docs/scalar-2014-slides.pdf?raw=true.
You can declare and compile a Scala class from a data structure description. It requires that you a) construct a syntactically correct class description and save it to a file (or equivalent) and then b) compile that class description to object code (i.e., a .class file). You can then load the class and use it.
This is not for the faint of heart. You need to understand the process of translation, compilation, class-loading and dynamic class binding. Even more important, you have to answer how you would actually use this in a program.
An example of dynamic class creation occurs in the Scala Play framework, where a presentation template files are translated into Scala and compiled into class files that can then be referenced from other Scala source code.

Scala: Difference between file.class and file$.class from scalac

When I use scalac to compile file.scala, I end up with 2 outputs, file.class and file$.class. What is the difference between these files and which is the appropriate one to then run? I get distinctly different error messages between executing "scala file" vs "scala file$".
Scala objects get compiled to classes ending in "$" because you're allowed to have an "ordinary" class with the same name. But the object's methods are also exposed as static methods on the "ordinary" class, so that they can be called under the names you would expect. This is an artifact of trying to represent the scala semantics in a way that make sense to Java / the JVM, and I would encourage you to regard it as an implementation detail rather than something important.
(#MattPutnam's answer is correct that anonymous classes, including closures, are compiled to class files with $es in their name, but that's not what's causing your file$.class in this particular instance)
Use scala file. If you're interested in the implementation details you might also want to try java -cp /path/to/scala-library.jar file.
file$.class is some inner anonymous class. In Java they're very explicit, but they can be easy to miss in Scala. If you use any method that takes a function, there's an implicit anonymous class there. Post the code and I'll point it out.

Scala style: More than one class in a file?

Unlike Java, Scala supports putting multiple classes in one file. Since Scala's classes are often quite short (think case classes), this often seems to make sense.
What is considered the proper style and idiom to do this, on production code? Under what circumstances should short or associated classes be put in the same file? How should that file be named?
This is all covered in Scala style guide
Summary :
As a rule of thumb, you should have one logical compilation unit (i.e
trait, class, object) per file.
Exception made of companion objects
where you can have them as well as their original trait/class in the
same file
Another exception is sealed trait with its subclasses
Last exception is if it makes way more sense maintenance wise (i.e your logical compilation units forms a inseparable, cohesive group)
Multi-unit file should have a lowercase first letter.