How to modify safely CCLabelBMFont String after first allocation created? - text

I have a member named _label as an ivar member in class :
#interface CCHelloWorldLayer : CCLayer
{
CCLabelBMFont *_label;
}
in another codeblock: initializing with this line:
_label = [CCLabelBMFont labelWithString:#"Testing " fntFile:fntName];
question is this:
if I want to modify its text what Should I do ?
I dont see any method like:
[_label setString:#"Well.there is no such a method"];
if I do
_label = [CCLabelBMFont labelWithString:#"Testing " fntFile:fntName];
_label = [CCLabelBMFont labelWithString:#"Well.there is no such a method"
fntFile:fntName];
is first memory allocation autoreleasing it self ?
is it safe to recall labelWithString method repeately ?
(note:I dont use ARC in test project.and I wont.)
thanks in advice

There is a setString method but it appears to be "private". The +labelWithString method does create an autorelease object and can be used repeatedly. It looks like it creates a texture, so you would want to create a new texture each time (as opposed to trying to modify it).
In general though, if you want the autoreleased object to stick around, you should retain it and release it when you're done.

[_label setString:#"Well.there is no such a method"];
This method exists and you can call it like that. Try it, it works.
The method is not declared in the class but in CCLabelProtocol.

Related

How to reference a class from a string which is part of a variable 3.7

I have just read a text file and extracted a string and stored it as a variable. This string also happens to be the name of a class I want to reference in order to use in a function for example. The "which_class" variable is the whichever class was stored in the file
I tried passing the which_class variable in as a parameter to the function. Removing the quotations seems to make it work but I am unsure how to do this.
class needed_for_func_one():
multiplier = 1.23
class needed_for_func_two():
multiplier = 1.15
def random_function(which_class):
print(123 * which_class.multiplier)
PSEUDO CODE
READ FROM FILE STORE STRING AS "which_class"
which_class = "needed_for_func_two"
random_function(which_class)
But this didn't work it just gave me an attribute error
the eval function could help you here.
random_function(eval(whichClass))
However, you should probably rethink whether you really want to it that way or if there is a much cleaner solution.
I think your question is related to this one
How you call the function depends if it is a global function or if it is inside an object.
globals()['call_this_function']() # this is probably what you need
or
getattr(from_this_object, 'call_this_function')()
first, to use a class you need an object of a class.
so if what you read is a name of the class or any other thing it does not matter, just use an if statement to decide what is inside that variable so-called "which_class".
then create an object like :
if which_class=="needed_for_func_one":
newObject = needed_for_func_one()
elseif which_class=="needed_for_func_two":
newObject = needed_for_func_two()
then use the print like :
print(123 * newObject.multiplier )

How to avoid duplication of class instances in Python?

What is a good way to avoid duplication of a class instance when it is created using the __init__() function.
This question is a result of this issue.
Context (using employee class example):
Lets say I have an employee class: __init__(self,name,dept)
I also have a method, employee.info(self) that prints out name and dept of any employee.
However a user could just add an employee by calling a=employee(args..). They could do it multiple times using the same instance variable a, but different employee names.
This will cause issues if they try to print a.info(), as each time a different employee name will be printed.
Is there a better way to do this? I know it is possible to have the __init__() "pass" and define a new method to create an instance.
Expect results:
>>Adam=employee('marketing')
>>Adam.info()
>>Adam works in marketing.
OR
>>a=employee('Adam','marketing')
>>a=employee('Mary','marketing')
>>Error: employee instance with identifier "a" already exists.
>>Use employee.update() method to modify existing record.
Is there a cleaner way of doing it? (as you might guess, I am still learning python).
Or is it good practice to write an explicit function (instead of a class method) to add new employees?
what you try is impossible, because in
a=employee('Adam','marketing')
a is not an object but a variable that points to the object employee('Adam','marketing').
When you do
a=employee('Mary','marketing')
you say to python that now, a must now not point to the object employee('Adam','marketing') but to the object employee('Mary','marketing'). And then, if you have no more variable to reference the object employee('Adam','marketing'), the garbage collector will destroy it.
You must consider that in python all is object, but not the variables that are only references to manipulate objects.
I have been racking my brains over the same problem and have finally managed to figure out a workaround :
Create a dictionary that stores the employee name and the related object like this :
total_emp_dict = {}
Add this inside the def __init__ of the class employee : total_emp_dict[name] = self. This will ensure to add each employee name as key and the object associated will be added as value.
Now create a new function outside & before the employee class is defined, let's call it create_new_emp. It will go like this :
#function to check and avoid duplicate assignment of instances
def create_new_emp(name, dept):
if name in total_emp_dict:
return total_emp_dict[name]
else:
return employee(name, dept)
When creating a any new employee, use this new function : a = create_new_emp("Adam", HR) instead of a = employee("Adam", HR)
Explanation : This function will ensure that duplicate assignment is not done. If "a" is already assigned to "Adam", this function will return object of "Adam" to "a", when called again. But if nothing is assigned to "a", then this function will handover to the attributes (name, dept) to employee class and create a new instance. This instance will then be assigned to "a".
I don't know if this is the best solution for this problem, but honestly this is the only solution I have found so far and it works great for me without much fuss / extra code space. Hope it works for you too! :)

Perl 6 - Is it possible to create an attribute trait that set a meta-attribute?

I try to create an attribute trait. The use case is to mark some attributes of a class as "crudable" in the context of an objects-to-documents-mapping while other are not.
role crud {
has Bool $.crud is default(True);
}
multi trait_mod:<is>(Attribute $a, crud, $arg) {
$a.container.VAR does crud($arg);
}
class Foo {
has $.bar is rw;
# Provide an extra nested information
has $.baz is rw is crud(True);
}
By reading and adapting some example code, I managed to get something that seems to do what I want. Here is a snippet with test case.
When I instantiate a new Foo object and set the $.bar attribute (that is not crud), it looks like that:
.Foo #0
├ $.bar is rw = 123456789
└ $.baz is rw = .Scalar+{crud} #1
└ $.crud +{crud} = True
What I understand from this is that the $.baz attribute got what I call a meta-attribute that is independent from its potential value.
It looks good to me (if I understood correctly what I did here and that my traits use is not a dirty hack). It is possible to reach $foo.baz.crud that is True. Though, I don't understand very well what .Scalar+{crud} means, and if I can set something there and how.
When I try to set the $.baz instance attribute, this error is returned:
Cannot modify an immutable Scalar+{crud} (Scalar+{crud}.new(crud => Bool::True))
in block <unit> at t/08-attribute-trait.t line 30
Note: This is the closest thing to a working solution I managed to get. I don't need different crud settings for different instances of instantiated Foo classes.
I never want to change the value of the boolean, in fact, once the object instantiated, just providing it to attributes with is crud. I am not even interested to pass a True or False value as an argument: if it would be possible to just set the boolean trait attribute to True by default, it would be enough. I didn't manage to do this though, like:
multi trait_mod:<is>(Attribute $a, :$crud!) {
# Something like this
$a.container.VAR does set-crud;
}
class Foo {
has $.bar is rw;
has $.baz is rw is crud;
}
Am I trying to do something impossible? How could I adapt this code to achieve this use case?
There are several things going on here. First of all, the signature of the trait_mod looks to be wrong. Secondly, there appears to be a bad interaction when the name of a trait is the same as an existing role. I believe this should be an NYI exception, but apparently it either goes wrong in parsing, or it goes wrong in trying to produce the error message.
Anyways, I think this is what you want:
role CRUD {}; # since CRUD is used as an acronym, I chose to use uppercase here
multi trait_mod:<is>(Attribute:D $a, :$crud!) { # note required named attribute!
$a.^mixin: CRUD if $crud; # mixin the CRUD role if a True value was given
}
class A {
has $.a is crud(False); # too bad "is !crud" is invalid syntax
has $.b is crud;
}
say "$_.name(): { $_ ~~ CRUD }" for A.^attributes; # $!a: False, $!b: True
Hope this helps.

Initialize class reference

I get null value of instrumentRented
when I run
public class RentalAgreement
{
private MusicalInstrument instrumentRented;
public RentalAgreement(Customer renter,
RentalDate dateRented,
MusicalInstrument instrumentRented){
customer = renter;
rentalDate = dateRented;
instrumentRented = instrumentRented;
How to initialize MusicalInstrument reference in RentalAgreement?
Use this.instrumentRented = instrumentRented;
Since the parameter has the same name as the field attribute, you need to prefix with an explicit this to specify the scope.
You must instantiate a class with the new operator.
So somehwere in your code must do
instrumentRented = new MusicalInstrument();
before you access it. After you have done this you can execute functions from that class.
instrumentRented.doSomething();
In the above code you seem to pass it in in the constructor, so this means the caller has to instantiate it.
However I would advise to adopt a naming convention where you can see if a variable is a class member or a local variable. In your above code the local variable has the same name as the parameter, so it will not be set as a member variable, instead you assign it to itself. You might get a warning about this, depending on the evironment (Not sure about this but Eclipse definitely warns somethign like this). This is called shadowing, so what you need to do is:
this.instrumentRented = instrumentRented;

Return object to original position on TouchesEnded?

I am trying to do a very basic thing but I am new to this.
Basically I have a screen with a 3 objects that can move around,
I have implemented a method which I call when TouchesMoved happens -
if object X moves over main object the object X will be hidden.
What I want to do is when the object Y is released over the main object
it will return to the position it was moved from.
should this be implemented in the TouchesEnded?
what would the method look like?
Any help would be very appreciated.
All you'd have to do here, is remember the object position in touchesBegan: and then restore the object in touchesEnded:
If you're only accepting single touches, then you can use something like this in the touchesBegan / touchesEnded methods to grab the touch...
CGPoint location = [[touches anyObject] locationInView:self];

Resources