I'm working with objects in octave and I would like to call the superclass set method in the subclass set. In the GNU octave documentation I haven't found how its works so I've tried to use the matlab documentation syntax but I get the next error: '' undefined near line 20 column 5 where the call is.
¿How could I access the superclass method correctly?
Here the code:
function s = set (o, varargin)
s = o;
if (length (varargin) < 2 || rem (length (varargin), 2) != 0)
error ([mfilename " :::: Expecting property/value pairs."]);
endif
while (length (varargin) > 1) #We get the first 2 pairs while exist.
prop = varargin{1};
val = varargin{2};
varargin(1:2) = [];
if (strcmp (prop, "color"))
if (ismember (val, ["black", "red", "green", "yellow", "blue", "violet", "cyan", "white"] )) #We check if val is a correct color.
s.color = val;
else
error ([mfilename " :::: Expecting the value for ""color"" to be a correct color."]);
endif
else
set#entity (s, prop,val);
endif
endwhile
endfunction
I'll add more details:
A simple example could be the next two classes:
try1, constructor and method (in his folder #try1):
function t = try1(x)
t.n = x;
t = class (t, "try1")
endfunction
function o = op(t,x)
o = t.n + x;
endfunction
try2 inherits from try1, constructor and method(in his folder #try2):
function t2 = try2(x)
t1 = #try1(x);
t.n = x;
t2 = class (t, "try2",t1);
endfunction
function o = op(t,x)
o = t.n - x;
endfunction
How to acces to op method of try1 with an instance of try2?
thanks :)
If you want to access the constructor of the parent class, just call it as you would normally outside the child class. Like so:
$ cat #try1/try1.m
function t = try1 (x)
t.n = x;
t = class (t, "try1");
endfunction
$ cat #try1/op.m
function o = op (t)
disp ("op() from try1");
o = t.n + 5;
endfunction
$ cat #try2/try2.m
function t2 = try2 (x)
t1 = #try1 (x);
t.n = x;
t2 = class (t, "try2", t1);
endfunction
$ cat #try2/op.m
function o = op (t)
o = op (t.t1);
endfunction
$ octave
octave:1> try2 (5)
ans = <class try2>
octave:2> op (ans)
op() from try1
ans = 10
See the manual section on Object Oriented Programming, specially the section on Inheritance and Aggregation
Related
Is it possible to conditional assign a value in one line in kotlin?
Setup
var foo: String
if (x != 0) {
foo = x
}
Goal
// nothing is set if condition is false
foo = if (x != 0) x
Not wanted
// null is set if condition is false
foo = takeIf{ x != 0 }.let{ x }
Is
foo = if (x != 0) x else foo
you want?
(Besides, you declared var foo: String, and the x != 0 may indicate a x: Int, then you are not able to foo = x. Maybe a typo here.)
Sure thing
if (x != 0) foo = x
The usual way of doing this would be the following:
if (x != 0) foo = x
This is not always possible, because smart casting cannot be performed if there is a chance that another thread modifies the value between the null check in the assignment. This happens for instance if your x is a nullable var property on the class.
In that case, you have this option:
x?.let { foo = it }
I'm learning how to use Lua and Love2d and I want to create a Vec2 class using metamethods and metatables. This is what I have so far:
class.lua: (The base class files)
local Class = {}
Class.__index = Class
-- Constructor
function Class:new() end
-- Inherite from Class
-- type = The name of the new class
function Class:derive(type)
print("Class:", self)
local cls = {}
cls["__call"] = Class.__call
cls.type = type
cls.__index = cls
cls.super = self
setmetatable(cls, self)
return cls
end
function Class:__call(...)
local inst = setmetatable({}, self)
inst:new(...)
return inst
end
function Class:getType()
return self.type
end
return Class
vec2.lua
local class = require "class"
local Vec2 = class:derive("Vec2")
function Vec2:new(x, y)
self.x = x or 0
self.y = y or 0
getmetatable(self).__add = Vec2.add
end
function Vec2.add(a, b)
local nx, ny
nx = a.x + b.x
ny = a.y + b.y
return Vec2:new(nx, ny)
end
return Vec2
and in my main.lua I have:
local v1 = Vec2:new(10, 10)
local v2 = Vec2:new(5, 3)
local v3 = v1 + v2
print("v3:", v3.x, v3.y)
and I get this error:
Error: main.lua:12: attempt to perform arithmetic on local 'v1' (a nil
value)
Vec2.new does not return a value. Hence the assignment local v1 = Vec2:new(10,10) results in v1 being nil
Try local v1 = Vec2(10,10) instead. Same mistake in Vec2.add
The instance is created in the __call metamethod which calls new with your parameters. You're not supposed to call new directly unless you want to re-initialize an existing instance.
function Class:__call(...)
local inst = setmetatable({}, self)
inst:new(...)
return inst
end
let set n v = Thread.delay 1.0; (n := v) in
let result1 x = set x (!x + 1) in
let result2 x = set x (!x * !x) in
let run i =
let original = 2 in
let r = ref (original) in
let t1 = Thread.create result1 r; let v1 = !r in
let v2 = !(result2 r) ;
Thread.join t1 ;
Printf.printf "number is %n" (v1 + v2) in
let main() =
run 1;
run 2 in
main() ;;
In the above program, I am using threads but could not figure out where the syntax error is. If anyone could help me to figure out what the error is.
This line:
let t1 = Thread.create result1 r; let v1 = !r in
Has two lets but only one in. I think you need another in here.
As a side comment, this is an unidiomatic way to structure your code at the top level of a file. It would be more usual to have a series of top-level definitions, which use let but not in. So it would look something like this:
let set n v = Thread.delay 1.0; (n := v)
let result1 x = set x (!x + 1)
let result2 x = set x (!x * !x)
let run i =
let original = 2 in
let r = ref (original) in
let t1 = Thread.create result1 r in
let v1 = !r in
let v2 = !(result2 r) in
Thread.join t1;
Printf.printf "number is %n" (v1 + v2)
let main () = run 1; run 2
let () = main ()
(I haven't compiled this so there might be a few syntax errors, apologies in advance. Just trying to show the basic layout.)
I have a recursive function fact, which can be called from either an expression inside it or an expression outside it.
I would like to associate fact with a variable v, such that each time fact is called from outside (another function), v is initialized, and its value can be changed inside fact, but never can be initialized when fact is called from inside.
The following code suits my need, but one problem is that v is defined as a global variable, and I have to do v := init before calling fact from outside, which I do not find beautiful.
let init = 100
let v = ref init
let rec fact (n: int) : int =
v := !v + 1;
if n <= 0 then 1 else n * fact (n - 1)
let rec fib (n: int) : int =
if n <= 0 then 0
else if n = 1 then (v := !v + 50; 1)
else fib (n-1) + fib (n-2)
let main =
v := init;
print_int (fact 3);
print_int !v; (* 104 is expected *)
v := init;
print_int (fib 3);
print_int !v;; (* 200 is expected *)
Could anyone think of a better implementation?
You can hide the function and value definitions within the body of a containing function as follows:
open Printf
let init = 100
let fact n =
let rec fact counter n =
incr counter;
if n <= 0 then 1 else n * fact counter (n - 1)
in
let counter = ref init in
let result = fact counter n in
(result, !counter)
let main () =
let x, count = fact 3 in
printf "%i\n" x;
printf "counter: %i\n" count (* 104 is expected *)
let () = main ()
You can adapt Martin's solution so that data is shared across various calls:
let fact =
let counter = ref 0 in
fun n ->
let rec fact = ... in
fact n
The idea is to transform let fact = fun n -> let counter = ... in ... into let fact = let counter = ... in fun n -> ...: counter is initialized once, instead of at each call of fact.
A classical example of this style is:
let counter =
let count = ref (-1) in
fun () ->
incr count;
!count
Beware however that you may get into typing trouble if the function was meant to be polymorphic: let foo = fun n -> ... is always generalized into a polymorphic function, let foo = (let x = ref ... in fun n -> ...) is not, as that would be unsound, so foo won't have a polymorphic type.
You can even generalize the counter example above to a counter factory:
let make_counter () =
let count = ref (-1) in
fun () ->
incr count;
!count
For each call to make_counter (), you get a new counter, that is a function that shares state across call, but whose state is independent from previous make_counter () counter creations.
With Ocaml's objects, you can do:
class type fact_counter = object ('self)
method get : int
method set : int -> unit
method inc : unit
method fact : int -> int
end;;
class myCounter init : fact_counter = object (self)
val mutable count = init
method get = count
method set n = count <- n
method inc = count <- count + 1
method fact n =
self#inc;
if n <= 0 then 1 else n * self#fact (n - 1)
end;;
Then you can obtain:
# let c = new myCounter 0;;
val c : myCounter = <obj>
# c#fact 10;;
- : int = 3628800
# c#get;;
- : int = 11
# c#set 42;;
- : unit = ()
# c#fact 10;;
- : int = 3628800
# c#get;;
- : int = 53
I hope you can easily see how to adapt myCounter to include fib ...
The Following is the basic skeleton for my MATLAB program. Each box is a class definition.
Scroll down for the error.
Note: 1. Each Class has a custom constructor
The Error
Undefined function or variable 'Troom'.
Error in ==> wall>wall.wall at 31
function o = wall(Tr)
Error in ==> mainfile at 5
w1 = wall();
This comes when I create an object of Class wall from another file "mainfile"
Question
Why is this happening?
Am I getting wrong in the concepts of OOP for Matlab specific?
How do I resolve this?
Thanks in Advance!
PS: Code
function o = wall()
Tr = o.Troom*2;
o.N = round(1/o.dx) + 1;
o.T = Tr * ones(o.N,1);
o.Tinf = Tr;
o.update_properties();
end
Code 2
classdef wall
properties
dx = 0.01;
dt = 0.4;
L = 0.16;
N;
tlimit = 1505.2;
sbc = 5.670400e-8 % The Stefan-Boltzmann Constant
a;
hi; % Surface Conductivity of Inner Surface
bi;
ho; % Surface Conductivity of Outer Surface
bo;
lamb;
Troom = 298; % Room Temperature (K)
Tinf;
T;
room = compartment();
conc = concrete();
fire = fireProperties(Troom);
end
room = compartment();
conc = concrete();
fire = fireProperties(Troom);
Yeah, there's your problem right there. Troom can't be used in the context of the properties block. Either put the constant in for Troom or move these into the constructor where they belong.