Set the value of an object from inside a method in Io - object

I'm trying to set the value of an object from inside a method. Here's an example:
myObject := list(1,2,3,4,5)
myObject drop := method(
self := list()
)
myObject drop
myObject println //returns original object
What am I doing wrong?

What you've done is create a new slot inside the method and named it self. Which means it goes away when the method returns. In Io self isn't a keyword, there are no keywords, and thus it doesn't have special meaning.
What you're looking for is to use a method that modifies self. Since List is written in C, you'd have to interface directly with something written in C, or with something that interfaces with something written in C, to clear the contents of the list. Consider:
myObject drop := method(
self empty
)
What's going on here is List has a method named empty which removes all items and returns the now empty object. It talks to a primitive List method called removeAll to accomplish this.
This is a bit cut and dry though. In the general case, in other circumstances, you may want to save the item you want to return BEFORE you remove it from the collection. i.e.,
myCollection drop := method(
result := self at(42)
self removeAllTheThings
result
)
Since not every type of collection that could exist, would have a removeAll or empty method built in.

Related

What is being copied when passing a string as parameter?

In Golang, everything is passed by value. If I pass an array "directly" (as opposed as passing it by pointer), then any modification made in the function will be found outside of it
func f(a []int) {
a[0] = 10
}
func main() {
a := []int{2,3,4}
f(a)
fmt.Println(a)
}
Output: [10 3 4]
This is because, to my understanding, an array constitutes (among other things) of a pointer to the underlying data array.
Unless I am mistaken (see here) strings also constitute (along with a "len" object) of a pointer (a unsafe.Pointer) to the underlying data. Hence, I was expecting the same behaviour as above but, apparently, I was wrong.
func f(s string) {
s = "bar"
}
func main() {
s := "foo"
f(s)
fmt.Println(s)
}
Output: "foo"
What is happening here with the string? Seems like the underlying data is being copied when the string is passed as argument.
Related question: When we do not wish our function to modify the string, is it still recommended to pass large strings by pointer for performance reasons?
A string has two values in it: pointer to an array, and the string length. When you pass string as an argument, those two values are copied, not the underlying array.
There is no way to modify the contents of string other than using unsafe. When you pass a *string to a function and that function modifies the string, the function simply modifies the string to point to a different array.

Groovy from 2nd dimentional array to 1 dimentional as string with prefix

I have an 2 dimentional array:
def test = [[88,3,2],[22,33,4],[88,3,3]]
test.sort
what i need now is to create each item into string and prefix it with string "test-"
so the end result would ne one dimentional array:
def endResult = ["test-88.3.2"],["test-88.3.3"],["test-22.33.4"]
if i do:
test.each {println it.join(".")}
it prints the first part but as written i need to save it and add prefix
im new to groovy any help would be great
The each method does not produce any result - it only iterates the input collection and allows you to do something with each element (e.g. print it to the console like in the example you showed in your question.)
If you want to manipulate each element of the collection and store it as a new collection, you can use the collect method which also takes a closure as a parameter. This closure is applied to each element of the input collection, and the return value of this closure is used to return a new collection from the collect method.
Something like this should do the trick for you:
def test = [[88,3,2],[22,33,4],[88,3,3]]
def endResult = test.collect { 'test-' + it.join('.') }
println endResult // [test-88.3.2, test-22.33.4, test-88.3.3]
It's worth mentioning that the closure we passed to the collect method uses so-called implicit return - there is no return keyword, but the value it produces from 'test-' + it.join('.') is returned implicitly.

Eiffel: how do I get the type of a particular operand of a procedure

As I can see into the debugger it's possible to get the operands, and name of procedure, is there a way to get it?
PROCEDURE=>operands returns a detachable that seems return the operands only when they have been setted into the agent
Do I have pass through any REFLECTOR class because the PROCEDURE class doesn't have this function and in this case why?
Seems that estudio has access to informations as ROUTINE client don't have, why is he a privileged one? is he cheating?
The following code demonstrates how to retrieve information about open argument types of a routine object:
p: ROUTINE -- Routine object.
t: TYPE [detachable ANY] -- Current open argument type.
do
p := agent (i: INTEGER; s: STRING)
do
end
across
1 |..| p.open_count as i
loop
t := p.generating_type.generic_parameter_type (1).generic_parameter_type (i.item)
io.put_string (t.name)
io.put_new_line
end
For me, the code above prints
INTEGER_32
!STRING_8
Comments:
p.open_count gives the total number of open arguments.
p.generating_type retrieves the type of the routine object.
p.generating_type.generic_parameter_type (1) retrieves the type of the open arguments tuple object.
The final call to generating_type retrieves the type of the open argument with index i.item.

In python 3, how can I convert a function into an attribute

I have a simple function I can call like this:
bln=getColN(bl,n)
I'd like to call it like this:
bln=bl.getColN(n)
The details don't matter, because I'd like to know how to do this in general, but since someone will surely ask: bl is a list of lists (a 2D array) and bln is a 1D list consisting of the nth column of bl. Yes, I'm sure I can do it with a comprehension.
I'm using python 3.4 on a win7 system.
What you want is a step from Structured Programming to Object Oriented Programming in the syntax sense. The older code may be designed using OO principles (or OO approach can be simply natural). Firstly, the bl must be the object if the second form is to be used. An object is known also as an instance of a class. This way, you have to define your class.
Then, bl variable represents the object. In Python, it is the reference to the object. The object is created when you call the class name. The bl is the name of the object from outside the class definition. The name of the same object from inside the class definition is named self by convention.
To put it together, your function will be converted to member function of the class, and you should probably only rename the arr (the first argument in the old function) in the old function definition to self (to stick with the conventions). However, if bl (from outside of the function definition, or arr from inside of the function definition) was a list in the old code, it becomes an object reference. Think about the object as about a thin wrapper around your list. There are basically two ways to do that (composition and inheritance). Usually, the composition should be the prefered way when you do such conversion (unless you know what you are doing). It means that the object must store what was earlier the reference to the list. In the class definition, you will use self.arr (or more suitable name) as the member variable for storing the reference to the list. To do that, you have to implement a special method (a method is also named as a member function) named __init__ (the underscores are doubled):
class MyArray:
def __init__(self, arr):
self.arr = arr
In Python, self. prefix must be always used explicitly inside the class definition if you want to refere to member variables or member functions.
Now add your getColN:
def getColN(self, n):
... change your body slightly...
Say you had def getColN(arr, n) in your existing function. Then arr was the reference to the list of lists. But now, the first argument of the function must be the reference to the object (i.e. class instance), and the array is now named self.arr. This way, you should rename your earlier arr in the function body to the self.arr. Now you have:
class MyArray:
def __init__(self, arr):
self.arr = arr
def getColN(self, n):
... changed body...
You can use the new class definition to wrap the existing list of lists in the sense you pass the old structure to the constructed object:
x = MyArray(bl)
The x will be your new replacement for the old bl. The old bl is passed to the __init__ -- seen as arr from inside the class definition, and saved as self.arr.
And you can call:
bln = x.getColN(n)
I did use the x identifier to emphasize the difference only. When refactoring (rewriting the old code), you may want to prefer to keep the bl identifier -- to reuse it for a different purpose:
bl = MyArray(bl)
The bl as argument was the list of lists, but later it becomes the object reference.
When everything works, you can add implementation of other special methods, and you can easily use syntax for your object of your own class as if it was an array (here using x again to emphasize the idea):
bln = x[n]

How a property, of type string, is passed

I have the following code (note the code below doesnt update the property)
private void queryResultsFilePath_Click(object sender, EventArgs e)
{
Library.SProc.Browse browser = new Browse();
browser.selectFile(QueryResultFilePath);
}
and
public class Browse
{
public void selectFile(string propertyName)
{
...
propertyName = browserWindow.FileName;
}
}
Now i realise that i need to change the second method so that it returns a string and manually assign it to the property in the first example.
What im unsure of is that i thought that when i assigned a ref type as an actual parameter of a method, a copy of its value on the stack (ie its memory address in the heap) was copied to the new location on the stack for the methods formal parameter, so they are both pointing to the same memory address on the heap. So when i changed the value of the formal parameter, it would actually change the value stored on the heap and thus the actual parameters value.
Obviously im missing something since im having to return a string and manually assign it to the property. If someone could point out what ive misunderstood id appreciate it.
Thanks.
I believe the missing piece here is: strings are immutable.
Although you pass it by reference, as soon as anything attempts to mutate the string, a new string is created leaving the old one intact.
I believe it is the only reference type that has enforced immutability.
From MSDN:
Strings are immutable--the contents of a string object cannot be
changed after the object is created, although the syntax makes it
appear as if you can do this. For example, when you write this code,
the compiler actually creates a new string object to hold the new
sequence of characters, and that new object is assigned to b. The
string "h" is then eligible for garbage collection.
Further reading:
http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/e755cbcd-4b09-4a61-b31f-e46e48d1b2eb
If you wish the method to "change" the caller's string then you can simulate this using the ref keyword:
public void SelectFile(ref string propertyName)
{
propertyName = browserWindow.FileName;
}
In this example, the parameter propertyName will be assigned to in the method, because of ref being used, this also changes the string that the caller is pointing to. Note here that immutability is still enforced. propertyName used to point to string A, but after assignment now points to string B - the old string A is now unreferenced and will be garbage collected (but importantly still exists and wasn't changed - immutable). If the ref keyword wasn't used, the caller would still point at A and the method would point at B. However, because the ref keyword was used the callers variable now points to string B.
This is the same effect as the following example:
static void Main(string[] args)
{
MyClass classRef = new MyClass("A");
PointToANewClass(ref classRef);
// classRef now points to a brand new instance containing "B".
}
public static void PointToANewClass(ref MyClass classRef)
{
classRef = new MyClass("B");
}
If you try the above without the ref keyword, classRef would still point to an object containing "A" even though the class was passed by reference.
Don't get confused between string semantics and ref semantics. And also don't get confused between passing something by reference and assignment. Stuff is technically never passed by reference, the pointer to the object on the heap is passed by value - hence ref on a reference type has the behaviour specified above. Also hence not using ref will not allow a new assignment to be "shared" between caller and method, the method has received its own copy of the pointer to the object on the heap, dereferencing the pointer has the usual effect (looking at the same underlying object), but assigning to the pointer will not affect the callers copy of the pointer.
I'm really grateful to Adam Houldsworth, because I've finally understood how the .NET framework uses reference parameters and what happens with the string.
In .NET there are two kind of data types:
value type: primitive types like int, float, bool, and so on
reference type: all the other objects, including string
In the case of reference type, the object is stored in the heap, and a variable only holds a reference pointing to this object. You can access the object's properties through the reference and modify them. When you pass one of this variables as parameter, a copy of the reference pointing to the same object is passed on to the method body. So, when you access and modify properties, you are modifyin gthe same object stored on the heap. I.e, this class is a reference object:
public class ClassOne
{
public string Desc { get; set; }
}
When you do this
ClassOne one = new { Desc = "I'm a class one!" };
there's an object on the heap pointed to by the reference one. If you do this:
one.Desc = "Changed value!";
the object on the heap has been modified. If you pass this reference as a parameter:
public void ChangeOne(ClassOne one)
{
one.Desc = "Changed value!"
}
The original object on the heap is also changed, because one helds a copy of the original reference that points to the same object on the heap.
But if you do this:
public void ChangeOne(ClassOne one)
{
one = new ClassOne { Desc ="Changed value!" };
}
The original object is unchanged. That's because one was a copy of the reference that it's now pointing to a different object.
If you pass it explicitly by reference:
public void ChangeOne(ref ClassOne one)
{
one = new ClassOne { Desc ="Changed value!" };
}
one inside this method is not a copy of the outer refernce, but the reference itself, so, the original reference now points to this new object.
strings are inmutable. This means that you cannot change a string. if you try to do so, a new string is created. So, if you do this:
string s = "HELL";
s = s + "O";
The second line creates a new instance of string, with the value "HELLO" and "HELL" is abandoned on the heap (left to be garbage collected).
So it's not possible to change it if you pass it as a parameter like this:
public void AppendO(string one)
{
one = one + "O";
}
string original = "HELL";
AppendO(original);
the original string is left as is. The code inside the function creates a new object, and assign it to one, which is a copy of original reference. But original keeps pointing to "HELL".
In the case of value types, when they are passed as parameters to a function, they are passed by value, i.e. the function receives a copy of the original value. So, any modification done to the object inside the function body won't affect the original value outside the function.
The problem is that, although string is a reference type, it looks as if it behaves like a value type (this applies to comparisons, passing parameters, and so on).
However, as explained above, it's possible to make the compiler pass a reference type by reference using the ref keyword. This also also works for strings.
You can check this code, and you'll see that the string is modified (this would also apply to an int, float or any other value type):
public static class StringTest
{
public static void AppednO(ref string toModify)
{
toModify = toModify + "O";
}
}
// test:
string hell = "HELL";
StringTest.AppendO(ref hell);
if (hell == "HELLO")
{
// here, hell is "HELLO"
}
Note that, for avoiding errors, when you define a parameter as ref, you also have to pass the parameter with this modifier.
Anyway, for this case (and similar cases) I'd recommend you to use the more natural functional syntax:
var hell = StringTest.AppendO(hell);
(Of course, in this case, the function will have this signature and corresponding implementation:
public static string AppendO(string value)
{
return value + "O";
}
If you're going to make many changes to a string, you should use the StringBuilder class, which works with "mutable strings".
How a property, of type string, is passed
Strings are immutable and therefore you are passing copies of them to methods. This means that the copy changes but the original parameter stays the same.

Resources