Can YamlDotNet Deserialize to an dynamic object graph? - deserialization

I have a large YAML document that I want to deserialize to a dynamic object (ExpandoObject). Can YamlDotNet deserialize directly to a dynamic object tree?
I can get there by going to Json first and then using NewtonSoft to deserialize to an ExpandoObject, but I'd rather skip that step.
using var input = new StreamReader("C:\\path\\to\\config.yaml");
var deserializer = new DeserializerBuilder()
.Build();
var yamlObject = deserializer.Deserialize(input);
var serializer = new SerializerBuilder()
.JsonCompatible()
.Build();
var json = serializer.Serialize(yamlObject);
dynamic config = JsonConvert.DeserializeObject<ExpandoObject>(json, new ExpandoObjectConverter());

Hello from the future,
I once, long ago, used this exact feature. However due to a lack of users and an desire to maintain it, it was split off from the main YamlDotNet libray.
You can find the source code here: https://github.com/aaubry/YamlDotNet.Dynamic
It is unlikely to work anymore but maybe you can adapt it if you need.
I know this answer probably isn't any help to you now, but I personally hate to see good questions with no answers so I hope this helps someone else.

Related

how can i solve this problem of dart null safety

this the screenshot of the error that i found
The compiler can't see what type data is, so it considers it as type Object. Object doesn't have a [] operator. Assuming that data is actually a Map you can try to replace
var data = doc.data();
with
Map? data = doc.data() as Map?;
Although there might be a nicer way to write this, but that's hard to know without seeing more of your code. Usually you can indicate the type already somewhere above it by using <Map> at the right place

Loop over listbuffer scala

I'm new in scala language I have a listbuffer :
var oldQuestions: Seq[Question] = section.questions
var newQuestions: ListBuffer[Question] = new ListBuffer()
So all I need is,to loop over the newQuestions list and access to one question based on her id and delete it.
Any help would be very appreciated.
Don't use vars, and mutable collections. It is a really, really rare occurrence that you actually need either of those in scala. So, for now, until you get sufficient grip on the language to be able to tell when those rare cases happen, just pretend these things don't exist. Learn to write good functional code before you explore mutability.
To answer your question:
val newQuestions: Seq[Question] = section.questions.filterNot(_.id == idToDelete)

Scala macros: Generate factory or ctor for Java Pojo

I'm currently working with reasonably large code base where new code is written in scala, but where a lot of old Java code remains. In particular there are a lot of java APIs we have to talk to. The old code uses simple Java Pojos with public non-final fields, without any methods or constructors, e.g:
public class MyJavaPojo {
public String myField1;
public MyOtheJavaPojo myField2;
}
Note that we dont have the option of adding helper methods or constructors to these types. These are currently created like old c-structs (pre-named parameters) like this:
val myPojo = new MyJavaPojo
myPojo.myField1 = ...
myPojo.myField2 = ...
Because of this, it's very easy to forget about assigning one of the fields, especially when we suddenly add new fields to the MyJavaPojo class, the compiler wont complain that I've left one field to null.
NOTE: We don't have the option of modifying the java types/adding constructors the normal way. We also don't want to start creating lots and lots of manually created helper functions for object creation - We would really like to find a solution based on scala macros instead of possible!
What I would like to do would be to create a macro that generates either a constructor-like method for my Pojos or a macro that creates a factory, allowing for named parameters. (Basically letting a macro do the work instead of creating a gazillion manually written helper methods in scala).
Do you know of any way to do this with scala macros? (I'm certain it's possible, but I've never written a scala macro in my life)
Desired API alternative 1:
val myPojo = someMacro[MyJavaPojo](myField1 = ..., myField2 = ...)
Desired API alternative 2
val factory = someMacro[MyJavaPojo]
val myPojo = factory.apply(myField1 = ..., myField2 = ...)
NOTE/Important: Named parameters!
I'm looking for either a ready-to-use solution or hints as to where I can read up on making one.
All ideas and input appreciated!
Take a look at scala-beanutils.
#beanCompanion[MyJavaPojo] object MyScalaPojo
MyScalaPojo(...)
It probably won't work directly, as you classes are not beans and it's only been made for Scala 2.10, but the source code is < 200 lines and should give you an idea of where to start.

Updating data in SORM seems possible (even though I was told it aimed at immutable data...)

I was told that SORM aims at immutable data. It's not written on the website - at least not in the main parts I was looking at, so I was a bit surprized of the rigidity of the claim. I was just aware it would recommend to do so. But maybe I was just missing something.
The examples tell you to use a ".copy(propery = newvalue)" before calling a Db.save() on the object. So thats a hint.
I was interrested in what would happen if I would just change the data and update it in the database. Strangely the following just worked fine:
case class Agent( var name : String )
object Db extends Instance(
entities = Set( Entity[Agent]() ),
url = "jdbc:h2:mem:hansi"
)
class SORMTest extends FunSuite {
test("Update") {
// Store values in the db:
val agent = Db.save( Agent("test") )
agent.name = "hansi"
Db.save(agent)
}
It produced an update statement in the database that changed the name property for the corresponding id.
Is it kind of crazy to do so? Any comments from the developers?
I was told that SORM aims at immutable data. It's not written on the website
It's stated plenty of times that SORM strongly follows functional programming idioms. This implies operation on immutable data-structures only.
The examples tell you to use a ".copy(propery = newvalue)" before calling a Db.save() on the object.
That's where you're wrong. The examples tell you to use .copy(..) to get an updated immutable value of the object it's called on, calling it before calling a Db.save() per se as in the following:
agent.copy(name = "new name")
Db.save(agent)
will have absolutely no effect, because, once again, .copy() doesn't mutate the object it's called on, instead it returns an updated copy of this object. So the proper use is the following:
val updatedAgent = agent.copy(name = "new name")
Db.save(updatedAgent)
or simply:
Db.save( agent.copy(name = "new name") )
But the fact is all the above has to do with SORM only as much as it has to do with functional programming in Scala in general. This is really a very basic stuff about how case classes are supposed to be used. So please do yourself a favor and introduce yourself to basics of functional programming. This will wipe out all the questions on SORM you've already had and, I'm sure, plenty of those which are comming up otherwise.
Your example works and it's supposed to, but it doesn't change the fact that it goes against the basic idioms of functional programming and as such is an unidiomatic use of SORM.

Storing an object to a file

I want to save an object (an instance of a class) to a file. I didn't find any valuable example of it. Do I need to use serialization for it?
How do I do that?
UPDATE:
Here is how I tried to do that
import scala.util.Marshal
import scala.io.Source
import scala.collection.immutable
import java.io._
object Example {
class Foo(val message: String) extends scala.Serializable
val foo = new Foo("qweqwe")
val out = new FileOutputStream("out123.txt")
out.write(Marshal.dump(foo))
out.close
}
First of all, out123.txt contains many extra data and it was in a wrong encoding. My gut tells me there should be another proper way.
On the last ScalaDays Heather introduced a new library which gives a new cool mechanism for serialization - pickling. I think it's would be an idiomatic way in scala to use serialization and just what you want.
Check out a paper on this topic, slides and talk on ScalaDays'13
It is also possible to serialize to and deserialize from JSON using Jackson.
A nice wrapper that makes it Scala friendly is Jacks
JSON has the following advantages
a simple human readable text
a rather efficient format byte wise
it can be used directly by Javascript
and even be natively stored and queried using a DB like Mongo DB
(Edit) Example Usage
Serializing to JSON:
val json = JacksMapper.writeValueAsString[MyClass](instance)
... and deserializing
val obj = JacksMapper.readValue[MyClass](json)
Take a look at Twitter Chill to handle your serialization: https://github.com/twitter/chill. It's a Scala helper for the Kyro serialization library. The documentation/example on the Github page looks to be sufficient for your needs.
Just add my answer here for the convenience of someone like me.
The pickling library, which is mentioned by #4lex1v, only supports Scala 2.10/2.11 but I'm using Scala 2.12. So I'm not able to use it in my project.
And then I find out BooPickle. It supports Scala 2.11 as well as 2.12!
Here's the example:
import boopickle.Default._
val data = Seq("Hello", "World!")
val buf = Pickle.intoBytes(data)
val helloWorld = Unpickle[Seq[String]].fromBytes(buf)
More details please check here.