Hi there another quick question.
I would like to create a variable object so that depending on the value of something, it gets cast as needed. e.g.
var rule;
switch (seqRuleObj.RuleType) {
case SeqRuleObj.type.Pre :
rule = new preConditionRuleType();
rule = (preConditionRuleType)seqRuleObj.Rule;
break;
case SeqRuleObj.type.Post :
rule = new postConditionRuleType();
rule = (postConditionRuleType)seqRuleObj.Rule;
break;
case SeqRuleObj.type.Exit :
rule = new exitConditionRuleType();
rule = (exitConditionRuleType)seqRuleObj.Rule;
break;
default :
break;
}
String result;
foreach (sequencingRuleTypeRuleConditionsRuleCondition cond in rule.ruleConditions.ruleCondition) {
....../ blah
}
so basically this will not work. c# will not allow me to create an new object in every case as the name is aleady defined.
i can just paste the foreach loop into each case but that to me is such a waste, as the objects are exactly the same in all but name.
Do these types inherit from a common class or implement a common interface? If so, then instead of using var rule, declare rule to be of the base type/interface.
If they do not have a common class/interface and you have control over these types, then create a base class/interface for them.
Related
I want to create specific Object according to the type argument.
Pseudo code looks like this.
sub new {
my $type = shift;
if($type eq "S1") {$interface = X->new(); }
if($type eq "S2") {$interface = Y->new(); }
etc...
return $interface;
}
Options might be:
Substitute "package" name with $type argument. Requires package name coordination with $type.
Use Hash{S1 => X} in the Master constructor to select Value according to $type passed. Requires Hash maintenance when adding new
Object types.
I don't like any of above. Looking trully polimorphic way to accomplish that.
Thank You,
k
Your best option would likely be to use a factory pattern. A factory method takes the parameters for creating an instance of your class, then decides which object to instantiate and return from that. This can also make dependency injection easier for testing.
You'd probably be looking at something like this (in Java-esque code), with an employee object:
public class EmployeeFactory
{
public static create(String type)
{
switch (type) {
case type1:
return new EmployeeTypeOne();
case type2:
return new EmployeeTypeTwo();
default:
throw new Exception("Unrecognized type");
}
}
}
Your employees would inherit from a common interface or abstract class. You can use the factory to handle constructor parameters as well if you prefer, just try to keep things fairly reasonable (don't pass a million parameters - the factory should internally handle complex objects)
See http://refactoring.com/catalog/replaceConstructorWithFactoryMethod.html for more information.
You might like Module::PluginFinder for that. Create all your specific types in a specific namespace and give them each some identifying (constant? sub?) that the main dispatcher will then use to identify which class handles a given type.
OK, what I'm trying to do is fairy complicated, but I'll try to explain.
Let's say we want (at compile-time) all derivedMembers of class someClass. Then we'd simply do :
const string[] methods = [__traits(derivedMembers,someClass)];
Now, how could we get someClass from "someClass"? (yep, its string representation).
Let me explain a bit more what I'm trying to do :
I want to create an "intermediate" function which takes a function name as an argument (along with a params array) and calls the appropriate function from a list of available static methods in a specific (predefined) set of classes. Like execute("someFunc",["one","two","three"]);.
Here's the full (test) code :
class Math {
static string noArgs(string[] s) { writeln(s); return ""; }
static string withOneArg(string[] s) { writeln(s); return ""; }
static string withTwoArgs(string[] s) { writeln(s); return ""; }
}
string cases()
{
string ret = "";
const string[] methods = [__traits(derivedMembers,Math)];
foreach (string s; methods)
{
ret ~= "case \"" ~ s ~ "\": return Math."~s~"(params);";
}
return ret;
}
string execute(string what, string[] params)
{
switch (what)
{
mixin(cases());
default: break;
}
return "";
}
The trouble with the above code is that it only looks for methods in Math. How could I change it, in an elegant D-friendly way, so that it'll go through an array of classes like [Math,String,SomethingElse] -- it doesn't have to be variable (we need it at compile-time anyway)?
UPDATE:
Tried something along the lines of :
const string[] methods = [__traits(derivedMembers,mixin("Math")];
but it complains that Cannot interpret Math at compile time.
UPDATE 2:
Also, tried using Object.factory("Math") but it's still not working. (Perhaps I'm just creating an instance of the Math class?)
Let me rewrite this to show you some cool tricks:
import std.stdio;
class Math {
static string noArgs(string[] s) { writeln(s); return ""; }
static string withOneArg(string[] s) { writeln(s); return ""; }
static string withTwoArgs(string[] s) { writeln(s); return ""; }
}
class String {
static string oneArg(string[] s) { return null; }
}
string execute(string what, string[] params) {
import std.string;
auto parts = what.split(".");
auto className = parts[0];
auto methodName = parts[1];
import std.typetuple;
switch(className) {
default: assert(0, "unknown class");
foreach(possibleClass; TypeTuple!(Math, String)) {
case possibleClass.stringof:
switch(methodName) {
default: assert(0, "unknown method");
foreach(memberName; __traits(derivedMembers, possibleClass)) {
case memberName:
return __traits(getMember, possibleClass, memberName)(params);
break;
}
}
break;
}
}
assert(0);
}
void main() {
execute("Math.withOneArg", ["cool"]);
execute("String.oneArg", ["cool"]);
}
Notice that there are no mixin expressions used at all. Instead of getting an instance of the class from a string, I just made a TypeTuple of all the classes I wanted to use. This is preferable to mixin because then it is less likely to find name classes when used in different scopes; if possibleClasses were a compile-time parameter to execute from a different module, the list of classes would still work, whereas the list of strings would see undefined identifier errors because the library module doesn't import your user module.
Another mixin I removed was the one to generate the cases. This looks insane, but is allowed in D: if you have a compile-time foreach (that is, a foreach over a built-in tuple of some sort, e.g. TypeTuple, template argument lists, the results of __traits...) you can actually put case statements inside them!
So, all you have to do is write a regular switch statement on the run time variable you want to compare against, put the foreach inside it looping over the compile-time stuff you're searching for, case that_loop_var: and boom, you're in business.
Similarly, I used __traits(getMember) rather than a mixin string to call the method. This solution will help avoid name clashes and IMO is cleaner code. It can also potentially handle overloads, if wanted (with __traits(getOverloads) instead of __traits(getMember), you can loop over each one then and match the parameter types).
Finally, nesting switches inside other case statements is allowed. If you need to break out of an outer loop or switch and don't want ambiguity, you can label loops and switches and use break label_name_here; to specify which one you want to break from. Ditto for continue with nested loops.
BTW you could also automatically generate the wrapper functions that convert string[] to other types of arguments if you dove into the std.traits stuff. I wish my book was out already, I wrote about this at some length in there and don't feel like writing it all right now but if you look at std.traits.ParameterTypeTuple and ReturnType in the same module that will get you started if you wanna try it.
I have a Report class that several models inherit from (OverviewReport, CategoryReport, etc...). Each of these inherited classes has specific methods/attributes that need to be customized for that type of report.
The desired report type is passed in via the params hash, so I can do something like the following:
# reports_controller.rb
def index
case params[:type]
when "overview" then OverviewReport.new(...)
when "category" then CategoryReport.new(...)
...etc...
end
end
This works, but I would like to clean up the controller a little bit. I would like to be able to do this:
# reports_controller.rb
def index
#report = Report.new(params[:type], ...)
end
# report.rb class
def initialize(type, options)
case type
when "overview" then self = OverviewReport.new(type, options)
when "category" then self = CategoryReport.new(type, options)
end
end
However, you can't change the value of self, so how would you go about accomplishing this functionality?
The intent is the clean up the controller code and abstract away which report you're using, so I can call #report.some_method() and it will call the inherited-specific method.
Is there a clean solution to this, or am I stuck with a (somewhat) lengthy case statement in my controller?
One solution would be to use a "factory" class whose sole purpose is to instantiate the correct class:
# reports_controller.rb
def index
#report = AgnosticReport.new(type)
end
# agnostic_report.rb
def initialize(type)
case type
when "overview" then return OverviewReport.new(type)
when "category" then return CategoryReport.new(type)
...etc...
end
end
This is perfectly acceptable, but I was wondering if there was any need to add a "third" layer of classes to this situation.
Do you have the ability to change the type params passed?
If so I would use constantize
params[:type] being "Overview Report" or "Category Report" e.t.c.
then use
#report = params[:type].constantize.new
s = "OverviewReport",
s.constantize => OverviewReport
I'm creating a JavaScript Framework for making applications in the classic Object-Oriented Programming (so with classes/interfaces instead of only prototypes). However I still have a problem with giving names to those.
For instance :
var Bidule = function() { /*...*/ } ;
Bidule.prototype = { /*...*/ } ;
Is Bidule a OOP Class as a class is a constructor ? Or is it only a constructor ?
As classes don't have prototypes, I don't think it could be called a true class.
So it means I should call them both 'Constructors'. However, what about an interface or an abstract class ? What is the correct word if they aren't constructors ? And is an interface a kind of class ?
I've designed constructor functions, classes and interfaces in my Framework. However I need a name to regroup all of theme so we may build one of those like this :
var Bidule = new _NAME_.Class(/*...*/) ; // Where _NAME_ is the name of the container of class/function/interface.
I was thinking of "Concept" but I'm not sure and would like to know your opinions.
I also named "visibility" the common word for describing public/private class,
"type" for static/abstract/interface/singleton/final class. Are those correct ?
And one last question : Is there a difference between the verb 'extend' and 'inherit' ?
Thanks in advance for your answers.
Javascript is not a traditional OO language, it is prototyped. Some concepts about OO cannot be applied to js for this reason.
Bidule is your type, so it is your "class". The constructor is the function you assined to the variable.
var Bidule = function() { /*...*/ } ;
Bidule.prototype = { /*...*/ } ;
var obj = new Bidule();
obj.foo = 'bar';
var obj2 = new Bidule();
obj2.foo = 'foo';
alert(obj instanceof Bidule); // true
alert(obj2 instanceof Bidule); // true
alert(obj.foo); // bar
alert(obj2.foo); // foo
Javascript does not support abstract classes or interfaces and no, interfaces are not some kind of classes. Interfaces defines contracts, or what your class does, but do not specify how.
Extend and inherit have the same meaning in this context.
For example suppose I have
class Parent {
def method() {
var myvar = "test"
}
}
Is there any mechanism for accessing myvar in child classes?
Edit:
I'm trying to build a DSL modeled upon an existing language. That language has features such as
onTrade {
if (price == ...) // will compile
}
onDayStart {
if (price == ...) // will not compile
}
It is as if price is a global variable but there are compile time checks to make sure it is only used in the correct context. I was thinking one way to simulate this would be to have local variables that could be overridden in subclasses. Something like
// Parent
onTrade {
var price = ...
}
// Child
onTrade {
if (price == ...)
if (somethingelse == ...) // will not compile
}
Not really. That's scope for you. If you want it to be visible at different levels, you should probably change the scope of the variable itself.
For example, if you want to define it at the class level, you can share it that way. Local variables wouldn't be local if they weren't actually, well, local.
Scopes are nested, from the most broad, to the most local. Chapter 2, pg. 16 of the Scala Language Reference covers "Identifiers, Names, and Scopes" which explains this in more technical detail.
Possible solution for your problem (though I don't see a way to get rid of new):
// parent
var onTrades = List[OnTrade]()
class OnTrade {
var price = ...
...
onTrades = this :: onTrades
}
// child
new OnTrade {
if (price == ...) {...} // subclass constructor, will call OnTrade constructor first
}