If I have an instance of A, are the instance variables implemented as pointers? In other words, are instance variables accessed by reference, even when using Structs?
class A
#title = "the title"
#my_val = MyStruct.new
end
#my_val is a reference to the instance of MyStruct on the stack. Checkout this example and notice the difference:
struct MyStruct
property x
def initialize(#x : Int32)
end
end
class A
getter my_val = MyStruct.new(10)
end
# mutates a struct (passed by reference)
def method(a : A)
a.my_val.x = 20
end
# does not mutate a struct (passed by value)
def method(s : MyStruct)
s.x = 30
end
a = A.new
p a.my_val.x #=> 10
a.method(a)
p a.my_val.x #=> 20
a.method(a.my_val)
p a.my_val.x #=> 20 (not 30)
Related
I have a c library that I bind to, which has many structs that hold data of different types.
#[Link("foo")]
lib LibFoo
struct IntStruct
data : LibC::Int
end
struct DoubleStruct
data : LibC::Double
end
fun get_int_struct(n : LibC::SizeT) : IntStruct*
fun get_double_struct(n : LibC::SizeT) : DoubleStruct*
end
I have a generic class where I want the type T to be the type of one of those structs, based off of an input array.
class GenericClass(T)
#ptr : Pointer(T)
#obj : T
def initialize(arr : Array)
#ptr = infer_type(arr)
#obj = #ptr.value
end
end
Where infer_type looks like:
def infer_type(data : Array(Int32))
return LibFoo.get_int_struct(data.size)
end
def infer_type(data : Array(Float64))
return LibFoo.get_double_struct(data.size)
end
The code works fine when I explicitly set the type...
GenericClass(LibFoo::IntStruct).new [1, 2, 3, 4, 5]
...but I would like to infer the type.
Maybe providing a custom generalized new method works for you?
struct A
end
struct B
end
class Generic(T)
def self.new(items : Array(A)) forall A
new(fetch_struct(items))
end
private def initialize(#struct : T)
end
private def self.fetch_struct(items : Array(Int32))
A.new
end
private def self.fetch_struct(items : Array(Float64))
B.new
end
end
p Generic.new([1])
p Generic.new([1.0])
https://carc.in/#/r/7s6d
I'm learning OCaml, and I'm a bit confused with the immutability of variables. According to the book I'm reading, variables are immutable. So far so good, but why on Earth can I do this:
let foo = 42
let foo = 4242
What am I missing??
I think the best way to explain is with an example. Consider this code (executed in the OCaml REPL):
# let foo = 42;;
val foo : int = 42
# let return_foo () = foo;;
val return_foo : unit -> int = <fun>
# let foo = 24;;
val foo : int = 24
# return_foo ();;
- : int = 42
The above code does the following:
Binds 42 to the name foo.
Creates a function return_foo () that returns the value bound to foo.
Binds 24 to the name foo (which hides the previous binding of foo).
Calls the return_foo () function, which returns 42.
Compare this with the behaviour of a mutable value (created using ref in OCaml):
# let foo = ref 42;;
val foo : int ref = {contents = 42}
# let return_foo () = !foo;;
val return_foo : unit -> int = <fun>
# foo := 24;;
- : unit = ()
# return_foo ();;
- : int = 24
which:
Creates a mutable reference containing 42 and binds it to the name foo.
Creates a function return_foo () that returns the value stored in the reference bound to foo.
Stores 24 in the reference bound to foo.
Calls the return_foo () function, which returns 24.
The name foo is first bound to an immutable value 42 and later it is rebound to another immutable value 4242. You can even bind the same name to variables of different types. In OCaml we are talking not about mutability of a variable, but about a mutability of a value. For example, if you bind foo to an array of values, this would be the same name, but bound to a mutable data, so that the value of a variable can change in time. Finally, each new binding just hides the previous one, so the original foo is still bound to 42, but it is invisible and will garbage collected.
Maybe a little example will clarify the idea:
let example () =
let foo = 42 in (* 1 *)
let foo = 4242 in (* 2 *)
let foo = [|42|] in (* 3 *)
foo.(0) <- 56 (* 4 *)
It might be easier to have the following mental model:
(*1*) +--------+
+----> | 42 |
+------------+ | +--------+
| +----+
| foo +----+ +--------+
| | +----> | 4242 |
+---------+--+ (*2*) +--------+
|
| (*3*) +--------+
+------------> |[| 42 |]|
(*4*) +--------+
On lines 1 and 2 we just bind a variable foo to two different values. On line 3 we bind it to an array that contains one element. On line 4, we change the value, and foo is still bound to the same value, but the value contains different datum.
I hope I didn't confuse you even more ;)
The usual form of let is the let ... in expression, where you define a variable binding, which only exists in the inside of the body of the let. The body of the let is a new scope.
let x = 42 in (* body here *)
Here the "body" of the let is a new scope that is different from the one outside, with all the variables from the outside with an additional local variable x that is only defined in the body of this let.
Now you are talking about lets at the top level of the file. These look a little different syntactically (there is no in), but really they are the same, with the "body" being the rest of the file. So here you can think of the rest of the file after the let as a new scope, with x being a local variable of this scope. So your code is equivalent to this:
let foo = 42 in (
let foo = 4242 in (
(* rest of file *)
)
)
Here your inner let binds a local variable that has the same name as a variable that already exists in the outer scope. That doesn't matter. You are binding a new variable in an inner scope. If it happens to have the same name as a variable in an outer scope, then code in the inner scope referencing that name will refer to the innermost binding. The two variables, however, are completely independent.
In a C-like language, it would be something like this:
{
const int foo = 42;
{
const int foo = 4242;
// rest of code here
}
}
See? There is no assignment to any variables here.
I am trying to overload the constructor to a class so that it can accept lists of two different types of objects:
class myClass(){
var someStrings: List[String]=List[String]()
println("hello!")
def this(strings : List[String])={
this()
this.someStrings=strings
}
def this(ints: List[Int])={
this()
this.someStrings=ints.map(x => x.toString)
}
}
In this case, accept a list of ints or strings, and save a list of strings to the variable someStrings. The code above doesn't work:
error: double definition:
constructor myClass: (strings: List[String])myClass at line 12 and
constructor myClass: (ints: List[Int])myClass at line 17
have same type after erasure: (strings: List)myClass
def this(ints: List[Int])={
^
Is there a better way of doing this in scala? (Other than taking List[Any] and testing the elements)
Thanks!
create functions on a companion object which do the construction for you in a typesafe way that can be checked at compile time:
class myClass(){
var someStrings: List[String]=List[String]()
println("hello!")
}
object myClass {
def fromStrings(strings: List[String]) = {
val c = new myClass
c.someStrings = strings
}
def fromInts(ints: List[Int]) = {
val c = new myClass
c.someStrings = ints.map(_.toString)
}
}
object Usage {
val c1 = myClass.fromStrings(List("a","b","c"))
val c2 = myClass.fromInts(List(1,2,3))
}
I would urge you to avoid overloading in general, or checking types at runtime, when you could be checking types at compile-time instead
That's what DummyImplicit is for:
def this(strings: List[String])={
this()
this.someStrings=strings
}
def this(ints: List[Int])(implicit d: DummyImplicit)={
this()
this.someStrings=ints.map(x => x.toString)
}
This makes the erased signatures of constructors (i.e. the ones JVM sees) MyClass(List) and MyClass(List, DummyImplicit), so the overloading is allowed.
However, as #stew says, it could be a better idea to avoid overloading in this case.
In addition to the other answer, another thing you can do is use Arrays. The type information on an array is kept at runtime, so you can do overloading based on the type parameter.
class myClass() {
var someStrings: Array[String] = Array[String]()
println("hello!")
def this(strings: Array[String]) = {
this()
this.someStrings = strings
}
def this(ints: Array[Int])={
this()
this.someStrings = ints.map(x => x.toString)
}
}
Arrays are much underused in my opinion
I have a question:
What is it mutable field ?
Is it connected with reference ?
If I can create mutable "without" creating record
Thanks in advcane!
Actually, references are implemented in terms of mutable fields:
a reference is just a record with a single (mutable) field named
contents, as you can see in your toplevel:
# let x = ref 1;;
val x : int ref = {contents = 1}
# x.contents;;
- : int = 1
# x.contents <- 2;;
- : unit = ()
# !x;;
- : int = 2
The main way to get mutable fields is to use records, and it is the
way you should prefer. Objects have mutable instance variables. You
can also get the equivalent of references by using one-element arrays.
Facing the error as :
AttributeError: 'function' object has no attribute 'd'.
how to access the dictionary?
code:
class A:
#staticmethod
def test():
d = {}
d['a'] = 'b'
print d
#staticmethod
def test1():
d1 = {}
d1['a'] = 'c'
if (A.test.d['a'] == A.test1.d1['a']):
print "yes"
else:
print "Oh No!!"
A.test()
A.test1()
Check out this on the matter of static variables in Python.
You should be able to sort it out using A.d and A.d1 whenever you wish to use the static variables. Note that, as you have them, they are local to test and test1, respectively. If you want them to be static, you have to declare them inside the class scope, but not within any function definition.