Making a Ruby string immutable - ruby

Need to make certain Ruby strings in my program to be immutable. What is the best solution? Writing a wrapper over String class?
The freeze method won't work for me. I see that freeze won't allow you to unfreeze the object.
Following is my situation: I have a class that passes a string to a callback. This string happens to be an instance variable of the class and can be potentially large. I don't want the callback to modify it, but still allow the class to modify it at will.

Following is my situation: I have a class that passes a string to a
callback.
Would passing a copy of the string to the callback work?
This string happens to be an instance variable of the class
and can be potentially large. I don't want the callback to modify it,
but still allow the class to modify it at will.
If you're worried about the size of the string, then using String#dup will help. It'll create a new object, with a distinct object_id, but the contents of the string won't be copied, unless the new string (or the original) gets modified. This is called "copy on write", and is described in Seeing double: how Ruby shares string values.

Call #freeze on the String. See: http://ruby-doc.org/core-1.9.3/Object.html#method-i-freeze

Related

Deleting an instance of a class via a method of that class

I have a class for pieces on a board. I want to be able to delete an instance of Piece so that anything else in the program that points to that piece will just point to nil.
Here's the very basic code version of what I want to do:
piece = Piece.new
variable = piece
variable #=> <Piece:0x0000000xxxxxxxx>
piece.delete
variable #=> nil
This seems like a very basic task so I feel like I'm missing something obvious. I've tried creating a delete method for the class with "self = nil", but this returns an error ("Can't change the value of self").
So far I have just worked around this by updating the other things that point to the object in my 'delete' method, but it seems like there should be a better way.
This is not possible.
Firstly, Ruby is an object-oriented language, which means that all manipulation is done via messages to objects, and all that is manipulated are objects. Variables are not objects, therefore you cannot manipulate them. (The only things you can do with variables are assign a value to them and dereference them.)
And even if you could manipulate variables, you would still need to hunt down every single reference to the object in question and remove it, in order for the object to be eligible for "deletion" (i.e. garbage collection).

Get Class of Map in FreeMarker

I want to get a variable's class type in freemarker, used var.class.simpleName;
but if var is a Map, freemarker will process class as a key to find value in var.
it throw exception. how can I do this ? thanks for any suggestion.
First I have to ask why do you need that, because FreeMarker templates aren't supposed to know even if var is Map at all. Maybe your data-model is not what the template needs.
Anyway, for now, I would write a custom TemplateMethodModelEx for this purpose, something that you can use like ${classOf(var)}. Inside the TemplateMethodModelEx implementation you will receive a TemplateModel as the argument value, and then you can check if it's an AdapterTemplateModel, and if so you can get back the original object and get its class. (If it's not a AdapterTemplateModel, then it perhaps isn't even a wrapped Java object, so it doesn't make sense to ask what the class of the original object is.) However, the DefaultObjectWrapper with incompatibleImprovements set to less than 2.3.22 doesn't give AdapterTemplateModel to wrapped Map-s... so in 2.3.21 you will still have to use BeansWrapper, but you can at least set simpleMapWrapper to true.
In 2.3.22 it will be actually possible to write ${var?api.class}... you might use the nightly build. Though it only supposed to solve the problem where you can't access business methods because the primary type of the business class is Map.

Referring to original object in With statement

I know that I can use a With statement to make repeated references to a single object:
With myObj
.StringProperty = ""
.BooleanProperty = False
End With
However, what I want to know is: is there a shorthand for referring to the original object in the With statement? In the above example, can I refer to myObj without explicitly typing myObj as I'm already working with it.
No you can't, but it wouldn't mean much anyway. With just sets the default scope to the object expression that follows it. If you need a reference to the object this doesn't help unless the object is one of the very few that has a .Self property, which is quite rare.

Coding Style: How to Make Obvious Determination of Parameter's Type We Have To Pass To a Function?

What is the best way to document the type of parameters that a function expects to receive?
Sometimes a function uses only one or two fields of an object. Sometimes this fields have common names (get(), set(), reset(), etc.). In this situation we must leave a comments:
...
#staticmethod
def get( postId, obj ):
"""obj is instance of class Type1, not Type2"""
inner = obj.get()
Is there a more explicit way to make it obvious? Maybe an object name should contain expecting typename?
Given python's 'duck-typing' (late bound) behaviour, it would be a mistake to require a particular type.
If you know which types your function must not take, you can raise an exception after detecting those; otherwise, simply raise an exception if the object passed does not support the appropriate protocol.
As to documentation, just put the required protocol in the docstring.
One strength of python is "duck typing", that is not to rely on the actual type of a variable, but on its behaviour. So I'd suggest, that you document the field, that the object should contain.
"""obj should have a field 'foo' like in class 'bar' or 'baz' """
First of all, name your methods properly, and use properties if they make sense.
You should try to get the hang of duck-typing. It's pretty useful. And if not, try and see if abstract base classes helps you do what you want.

Do I need to retain objects I receive in arguments?

If I have a method with input that is used do I have to retain?
- (void) exampleMethod: (NSString *)input {
self.hey = [input retain];
}
What if I use input more than once?
Read the Memory Management Rules. If hey is a property with the retain or copy attributes set, then you do not need to invoke -retain on it (you can just do self.hey = input).
You don't need to retain a parameter that you only intend to use during the method. If you are going to keep a reference to it longer (as you seem to be in your example), then in most cases you should.
However, if you are using a property (which again you seem to be here), you should be managing the memory within the property setter itself, not calling retain explicitly when calling the setter.
In this case, the assignment to the .hey property a retain is implict in the accessor method.
Accessor Methods
If you want to continue using the string without using an accessor method, you may need to retain the string and the scope with which you need to have it available.

Resources