I need to create a clone of an array of objects in Crystal.
cloned_person_array = persons.clone #[Person, Person, Person]
But I get the following error:
undefined method 'clone' for Person
Array(T).new(size) { |i| #buffer[i].clone.as(T) }
I realized that this method is not meant for non-primitives that are defined by the code. The documentation doesn't explicitly exclude it, but it does only show a primitive example.
How do you clone an array of objects in Crystal?
I can imagine performing a .map on the array and then returning a new array that way, but I'm curious if maybe I'm just using the clone method mentioned above incorrectly?
You need to define Person#clone yourself, to allow you to clone Array(Person).
An easy way to do this is the def_clone macro.
class Person
property name : String
def_clone
end
Related
First off, I'm new to c++, currently learning it online.
I greatly appreciate any help...
I have a vector of classes set up for vehicles, however it should also contain derived classes for vehicles of different types (car, truck, van).
My class is set up to have functions to gather user input and assign that to different variables, I do not use the constructor for this. Is that wrong?
In my main this all works fine and dandy but when I go to add the class to the vector I run into issues, first off, My instructor informed us to use smart pointers for this, so I initialize my vector like so...
vector<unique_ptr<Vehicle>> vehicles;
This is how I'm adding classes to that vector...
// For base class...
vehicles.push_back(make_unique<Vehicle>());
// For derived class...
vehicles.emplace_back(make_unique<Car>());
This is where I am stuck, adding the class this way will cause it to be called and therefor the constructor called as well. What I would like to do is just add a class that I have already created and defined beforehand, for example..
// Functions to gather user input, validate and display...
Vehicle vehicle;
vehicle.getMake();
vehicle.validateName(vehicle.make);
vehicle.getModel();
vehicle.validateName(vehicle.model);
vehicle.displayVehicle();
vehicles.push_back(/* Somehow add 'vehicle' */);
Thanks for any help, I understand this might be the wrong way to do this, I was just struggling to find a solution and this is currently where I am at.
My class is set up to have functions to gather user input and assign that to different variables, I do not use the constructor for this. Is that wrong?
A constructor shouldn't do lots of things, and never prompt for user input… but, at the same time, it should not be possible to have a "half-ready" object at any point. I suggest you gather all your user input first, then pass it into the constructor so your object is ready to go in one step.
(I have not shown this in the following example.)
This is where I am stuck, adding the class this way will cause it to be called and therefor the constructor called as well. What I would like to do is just add a class that I have already created and defined beforehand, for example..
Your vector contains unique_ptr<Vehicle>s, so you'll want to start off with one:
std::unique_ptr<Vehicle> vehicle = std::make_unique<Vehicle>();
vehicle->getMake();
vehicle->validateName(vehicle->make);
vehicle->getModel();
vehicle->validateName(vehicle->model);
vehicle->displayVehicle();
vehicles.push_back(std::move(vehicle));
Notice that all the vehicle. are now vehicle->, because vehicle is no longer an actual Vehicle but instead a pointer to one.
std::move is needed because unique_ptrs are not copyable, only moveable.
Taking my advice from the start of the answer, this gets somewhat simpler:
std::string make = GetMake();
ValidateName(make);
std::string model = GetModel();
ValidateName(model);
vehicles.push_back(std::make_unique<Vehicle>(make, model));
vehicles.back()->displayVehicle();
I've moved the displayVehicle call to the end, because it shouldn't make a difference to your output, but allows us to do the "construct Vehicle" and "put it into vehicles" steps simultaneously.
This approach assumes that you have altered your constructor to take make and model, and set up free function GetMake(), GetModel() and ValidateName() to do those tasks.
I am currently learning the OOP paradigm in C++ (my program must have a class for an object - ex: TrenchCoat, Repository- list of trench coats, Controller and User Interface). I must make a method in the Repository class that returns the trench coats with a given size. I have 2 choices:
1) I return an STL vector with the wanted objects
ex: std::vector filterBySize(int size);
2) In the method, I create another Repository and the wanted objects I add to this second Repository and return the Repository.
ex: Repository filterBySize(int size);
I don't know which choice is right.
To me, there is not a correct answer, the better solution depends on what do you want to do after the filter operation.
Returning a Repository objects, it makes easier further and different operations (for example another filtering by color). In fact, supposing that another method Repository filterbyColor(String color) exists in the Repository class, it could be called directly from the previous filter operation, as below:
Repository filteredRepo=repo.filterBySize(40).filterByColor('yellow');
Instead, if you don't need to perform further operations, you can simply return a vector.
I have a problem that I want to know if there is a magic trick or pattern to solve this in the other way.
I have list of B class objects, but I need to return list of A class objects. 'A' and 'B' classes have exactly the same fields (I need to return List, but I have List because it was mapped from database by hibernate) and I need to return it inside List of A objects because I can not import B class to other project (where class A is) beacuse of maven cyclic reference.
I just rewrote all fields from every object in for loop.
Is there any other way to solve this without doing it inside the loop?
Thanks in advance for discussion :)
Cheers! :)
Did you try returning Object type list? It could then be type-casted to B type .
In a perfect world you would extend both classes from one base class to make them copatible, but i see that this is not possible here.
in my opinion your approch is already the savest way to solve the problem.
another way would be to solve it over reflection. It's not recomendable - just pointing this out.
In this solution, you iterate over all declared fields of the given object, read out the value and set the field with the same name in your object to this value.
like i said, it's not recomendable because it relies on field names which may change.
I'm fairly new to c++ templates.
I have a class whose constructor takes two arguments. It's a class that keeps a list of data -- it's actually a list of moves in a chess program.
I need to keep my original class as it's used in other places, but I now need to pass extra arguments to the class, and in doing so have a few extra private data members and specialize only one of the private methods -- everything else will stay the same. I don't think a derived class helps me here, as they aren't going to be similar objects, and also the private methods are called by the constructor and it will call the virtual method of the base class -- not the derived method.
So I guess templates are going to be my answer. Just looking for any hints about how might proceed.
Thanks in advance
Your guess is wrong. Templates are no more the answer for your problem than inheritance is.
As jtbandes said in comment below your question, use composition.
Create another class that contains an instance of your existing class as a member. Forward or delegate operations to that contained object as needed (i.e. a member function in your new class calls member functions of the contained object). Add other members as needed, and operations to work with them.
Write your new code to interact with the new class. When your new code needs to interact with your old code, pass the contained object (or a reference or a pointer to it) as needed.
You might choose to implement the container as a template, but that is an implementation choice, and depends on how you wish to reuse your container.
Templates are used when you want to pass at compile time parameter like values,typenames, or classes. Templates are used when you want to use exactly the same class with the same methods, but applying it to different parameters. The case you described is not this I think.
If they aren't goign to be similar objects you may want to create a specialized class (or collections of function) to use from the various other classes.
Moreover you can think of creating a base class and extending it as needed. Using a virtual private method should allow you to select the method implementation of the object at runtime instead of the method of the base class.
We may help you more if you specify what does they need to share, what does your classes have in common?
The bare bones of my present code looks like this:
class move_list{
public:
move_list(const position& pos, unsigned char ply):pos_(pos),ply_(ply){
//Calculates moves and calls add_moves(ply,target_bitboard,flags) for each move
}
//Some access functions etc...
private:
//private variables
void add_moves(char,Bitboard,movflags);
};
Add_moves places the moves on a vector in no particular order as they are generated. My new class however, is exactly the same except it requires extra data:
move_list(const position& pos, unsigned char ply,trans_table& TT,killers& kill,history& hist):pos_(pos),ply_(ply),TT_(TT),kill_(kill),hist_(hist) {
and the function add_moves needs to be changed to use the extra data to place the moves in order as it receives them. Everything else is the same. I guess I could just write an extra method to sort the list after they have all been generated, but from previous experience, sorting the list as it receives it has been quicker.
As an example, a string that contains only a valid email address, as defined by some regex.
If a field of this type would be a part of a more complex data structure, or would be used as a function parameter, or used in any other context, the client code would be able to assume the field is a string containing a valid email address. Thus, no checks like "valid?" should be ever necessary, so approach of domaintypes would not work.
In Haskell this could be accomplished by a smart constructor (section 1.2) and in Java by ensuring the type is immutable (all setters private) and by adding a check in the constructor that throws a RuntimeException if the string used to create the type doesn't contain a valid email address.
If this is impossible in plain Clojure, I would like to see an example implementation in some well known extensions of the language, like Typed Clojure.
Ok, maybe, I understand now a question and I formulate in the comment my thoughts not really well. So I try to suggest an admissible solution to your question and then I try to explain some ideas I tried to tell in the comment.
1) There is a gen-class that generates compiled bytecode for a class and you can set constructor for the class there.
2) You can create a record with defrecord in some namespace that is private by convention in your project, then you
create another namespace with public api and define your factory function here. So the user of your public namespace will be able to call only public functions of your public namespace. (Of course, he can call also private ones, but with some another code)
3) You can just define a function like make-email that will return a map.
So you didn't specify your data structure anywhere.
4) You can just document your code where you will warn people to use the factory function for construction.
But! In Java if your code requires some interface, then it's user problem to give to your code the valid interface implementation. So if you write even a little bit general code in Java you already has lost the property of the valid email string. This stuff with interfaces is because Java is statically typed language.
Clojure is, in general, dynamically typed, so the user, in general, should be able to pass arbitrary data structure to arbitrary function without any type problems in compile time and it's his fault if he pass the wrong data. That makes, for example, this thing possible: You create a record and create a factory (constructor) function. And you expect a record to be passed in your code. But the user can pass a map with the same keys as your record fields names and the code will work.
So, in general, if you want the user of your code to be responsible for passing a required typed in dynamically typed language, then it cost nothing for user to be responsible for constructing it in a correct way that you provide to him.
Another solutions are: User just write tests. You can specify in your api functions :pre and :post conditions to check the structure. You can use typed clojure with the ideas I wrote above. And you can use some additional declarative libraries, like that was mentioned in the first comment of #Thumbnail.
P.S. I'm not a clojure professional, so I could easily miss some better solutions.