Julia: Understanding Multiple dispatch for OOP - oop

Lets say I have the following types:
type cat
cry:: String
legs:: Int
fur:: String
end
type car
noise::String
wheels::Int
speed::Int
end
Lion = cat("meow", 4, "fuzzy")
vw = car("honk", 4, 45)
And I want to add a method describe to both of them which prints the data inside them. Is it best to use methods to do it this way:
describe(a::cat) = println("Type: Cat"), println("Cry:", a.cry, " Legs:",a.legs, " fur:", a.fur);
describe(a::car) = println("Type: Car"), println("Noise:", a.noise, " Wheels:", a.wheels, " Speed:", a.speed)
describe(Lion)
describe(vw)
Output:
Type: Cat
Cry:meow Legs:4 fur:fuzzy
Type: Car
Noise:honk Wheels:4 Speed:45
Or should I use a function like in this question I posted before: Julia: What is the best way to set up a OOP model for a library
Which method is more efficient?
Most Methods examples in the documentation are simple functions, if I wanted a more complex Method with loops or if statements are they possible?

First of all, I recommend using a capital letter as the first letter of a type name - this is an extremely consistent thing in Julia style, so not doing it would definitely be awkward for people using your code.
As you are doing multi-statement methods, you should probably write them as full functions, e.g.
function describe(a::cat)
println("Type: Cat")
println("Cry:", a.cry, " Legs:", a.legs, " fur:", a.fur)
end
function describe(a::car)
println("Type: Car")
println("Noise:", a.noise, " Wheels:", a.wheels, " Speed:", a.speed)
end
Typically the one-liner version is used only for simple single statements.
May also be worth noting that we are making one function, with two methods, in case that wasn't clear from the manual.
Finally, you could also add a method to the base Julia print function, e.g.
function Base.print(io::IO, a::cat)
println(io, "Type: Cat")
print(io, "Cry:", a.cry, " Legs:", a.legs, " fur:", a.fur)
end
function Base.print(io::IO, a::car)
println(io, "Type: Car")
print(io, "Noise:", a.noise, " Wheels:", a.wheels, " Speed:", a.speed)
end
(if you call println, it'll call print internally and add the \n automatically)

Related

What is the purpose of the underscore after variable name and comma?

I found this Lua code:
function displayName(name)
name, _ = name:gsub("{", "\\{")
return name
end
and again:
function parsePath(path)
if type(path) == "string" then path, _ = path:gsub("\\", "/") end
return path
end
I understand what the code does.. what I don't understand is that , _ (comma underscore) between the variable name and the assignation part (=).. so this one name, _ = name:gsub("{", "\\{") and this one ..then path, _ = path:gsub("\\", "/")
Can someone explain to me the meaning of that thing ?
Wouldn't be name = name:gsub(....) or ..then path = path:gsub(...) the same ?
So why the script is written this way ?
In many programming languages _ is used to denote unused variables.
This is also applicable to Lua. It is pure style convention. You won't find anything about it in the Lua manual.
luackeck, the most common static code analyzer for Lua will give you warnings for having unused variables in your code. It will ignore variables named _ in that regard.
Wouldn't be name = name:gsub(....) or ..then path = path:gsub(...) the
same ?
In your examples this is actually not necessary.
The only reason to have _ in name, _ = name:gsub("{", "\\{") would be to give a hint that this function actually returns two values. Usually you would leave the _ away.
Whereas _, numReplaced = name:gsub("{", "\\{") would make sense if you're only interested in the second return value. You cannot get that without adding the first unused variable.
I am not an expert in Lua, but this pattern is used in other programming languages like Python. The underscore means "a variable that is not going to be used". If your function returns an array with two elements, then you need to do this, otherwise you are going to get the whole array.

Passing a block to .try()

This question is about using the .try() method in rails 3 (& a bit about best practice in testing for nil also)
If I have a db object that may or may not be nil, and it has a field which is eg a delimited string, separated by commas and an optional semi-colon, and I want to see if this string contains a particular sub-string, then I might do this:
user_page = UserPage.find(id)
if user_page != nil
result = user_page.pagelist.gsub('\;', ',').split(",").include?(sub)
end
So, eg user_page.pagelist == "item_a,item_b;item_c"
I want to re-write this using .try, but cannot find a way of applying the stuff after pagelist
So I have tried passing a block (from this link http://apidock.com/rails/Object/try)
user_page.try(:pagelist) {|t| t.gsub('\;', ',').split(",").include?(sub)}
However, the block is simply ignored and the returned result is simply pagelist
I have tried other combinations of trying to apply the gsub etc part, but to no avail
How can I apply other methods to the method being 'tried'?
(I dont even know how to phrase the question in an intelligible way!)
I think you're probably coming at this wrong - the quick solution should be to add a method to your model:
def formatted_pagelist
(pagelist || "").split(/[;,]/)
end
Then you can use it where ever:
user_page.formatted_pagelist.include? sub
Strictly speaking, I'd say this goes into a decorator. If you're not using a decorator pattern in your app (look into draper!), then a model method should work fine.

What do numbers in braces e.g. "{0}" mean?

I've been looking around but having great difficulty finding the answer to this question as the thing I'm looking for is so unspecific.
I've seen a lot of code which uses {0} in it, and I still can't work out what it's doing. Here's an example:
Dim literal As String = "CatDogFence"
Dim substring As String = literal.Substring(6)
Console.WriteLine("Substring: {0}", substring)
Console.WriteLine("Substring: {0}", substring)
Is the same as
Console.WriteLine("Substring: " & substring)
When using Console.WriteLine, {n} will insert the nth argument into the string, then write it.
A more complex example can be seen here:
Console.WriteLine("{0} {1}{2}", "Stack", "Over", "flow")
It will print Stack Overflow.
Console.WriteLine() and String.Format() use that syntax.
It allows you to inject a variable into a string, for example:
dim name = "james"
String.Format("Hello {0}", name)
That string will be "Hello james"
Using Console.Writeline:
Console.WriteLine("Hello {0}",name)
That will write "Hello james"
It's a placeholder. Beginning at the second parameter (substring in your case), they are included in the given string in the given order. This way you avoid long string concatenations using + operator and can do easier language localization, because you can pull the compete string including the placeholders to some external resource file etc.
It is called composite formatting and is supported by many methods, Console.WriteLine being one. Besides indexed placeholders there are other features available. Here is a link to the documentation that shows some of the other features of composite formatting.
Composite Formatting

Ada support for variables in put_line's?

Does Ada have support for something similar to an Obj-C variable in a string?
NSLog(#"This is text, here's a variable %f", floatvar);
I'd like to be writing nice one-liners, like:
put_line("The answer is %v", answer);
instead of
put_line("The answer is ");
put(answer);
You might like the Ada FAQ, specifically part 9.9. For completeness, I quote it here:
While the standard package Text_IO provides many features, the
request for a printf-like function is not unusual.
(solution based on a suggestion by Tucker Taft)
It is possible to produce a printf-like capability by overloading
the "&" operator to take an object of type Format and an object of
some type and return the Format, properly advanced, after having
performed the appropriate output. The remaining format can be
converted back to a string--e.g. to examine what is left at the end
of the format string-- or simply printed to display whatever
remains at the end. For example:
with Text_IO;
package Formatted_Output is
type Format is
limited private;
function Fmt (Str : String)
return Format;
function "&" (Left : Format; Right : Integer)
return Format;
function "&" (Left : Format; Right : Float)
return Format;
function "&" (Left : Format; Right : String)
return Format;
... -- other overloadings of "&"
procedure Print (Fmt : Format);
function To_String (Fmt : Format)
return String;
private
...
end Formatted_Output;
with Formatted_Output; use Formatted_Output;
procedure Test is
X, Y : Float;
begin
Print (Fmt("%d * %d = %d\n") & X & Y & X*Y);
end Test;
The private part and body of Formatted_Output are left as an
exercise for the reader ;-).
A "File : File_Type" parameter could be added to an overloading of
Fmt if desired (to create something analogous to fprintf).
This capability is analogous to that provided by the "<<" stream
operator of C++.
Assuming you have F : Float;, you can say
Put_Line (“the answer is “ & Float’Image (F));
This doesn’t work so well if you want neat formatting, because the format output by ’Image is fixed as specified in the ARM (that link’s actually to ’Wide_Wide_Image, not ’Image, but the format’s the same).
If you’re using GNAT, you could write the above as
Put_Line (“the answer is “ & F'Img);
which saves (a) characters and (b) remembering the type concerned, but that’s not portable.

How to comment on MATLAB variables

When I´m using MATLAB, sometimes I feel the need to make comments on some variables. I would like to save these comments inside these variables. So when I have to work with many variables in the workspace, and I forget the context of some of these variables I could read the comments I put in every one of them. So I would like to comment variables and keep the comments inside of them.
While I'm of the opinion that the best (and easiest) approach would be to make your variables self-documenting by giving them descriptive names, there is actually a way for you to do what you want using the object-oriented aspects of MATLAB. Specifically, you can create a new class which subclasses a built-in class so that it has an additional property describing the variable.
In fact, there is an example in the documentation that does exactly what you want. It creates a new class ExtendDouble that behaves just like a double except that it has a DataString property attached to it which describes the data in the variable. Using this subclass, you can do things like the following:
N = ExtendDouble(10,'The number of data points')
N =
The number of data points
10
and N could be used in expressions just as any double value would. Using this example subclass as a template, you could create "commented" versions of other built-in numeric classes, with the exception of those you are not allowed to subclass (char, cell, struct, and function_handle).
Of course, it should be noted that instead of using the ExtendDouble class like I did in the above example, I could instead define my variable like so:
nDataPoints = 10;
which makes the variable self-documenting, albeit with a little more typing needed. ;)
How about declaring another variable for your comments?
example:
\>> num = 5;
\>> numc = 'This is a number that contains 5';
\>> whos
...
This is my first post in StackOverflow. Thanks.
A convenient way to solve this is to have a function that does the storing and displaying of comments for you, i.e. something like the function below that will pop open a dialog box if you call it with comments('myVar') to allow you to enter new (or read/update previous) comments to variable (or function, or co-worker) labeled myVar.
Note that the comments will not be available in your next Matlab session. To make this happen, you have to add save/load functionality to comments (i.e. every time you change anything, you write to a file, and any time you start the function and database is empty, you load the file if possible).
function comments(name)
%COMMENTS stores comments for a matlab session
%
% comments(name) adds or updates a comment stored with the label "name"
%
% comments prints all the current comments
%# database is a n-by-2 cell array with {label, comment}
persistent database
%# check input and decide what to do
if nargin < 1 || isempty(name)
printDatabase;
else
updateDatabase;
end
function printDatabase
%# prints the database
if isempty(database)
fprintf('no comments stored yet\n')
else
for i=1:size(database,1)
fprintf('%20s : %s\n',database{i,1},database{i,2});
end
end
end
function updateDatabase
%# updates the database
%# check whether there is already a comment
if size(database,1) > 0 && any(strcmp(name,database(:,1)))
idx = strcmp(name,database(:,1));
comment = database(idx,2);
else
idx = size(database,1)+1;
comment = {''};
end
%# ask for new/updated comment
comment = inputdlg(sprintf('please enter comment for %s',name),'add comment',...
5,comment);
if ~isempty(comment)
database{idx,1} = name;
database(idx,2) = comment;
end
end
end
Always always always keep the Matlab editor open with a script documenting what you do. That is, variable assignments and calculations.
Only exceptions are very short sessions where you want to experiment. Once you have something -- add it to the file (It's also easier to cut and paste when you can see your entire history).
This way you can always start over. Just clear all and rerun the script. You never have random temporaries floating around in your workspace.
Eventually, when you are finished, you will also have something that is close to 'deliverable'.
Have you thought of using structures (or cells, although structures would require extra memory use)?
'>> dataset1.numerical=5;
'>> dataset1.comment='This is the dataset that contains 5';
dataset1 =
numerical: 5
comment: 'This is the dataset that contains 5'