How can I set global field in method - object

I have some problem, so I have a few global fields in class, for each I want to do the same code but I don't want to repeat code - just use one method for that. And there I want to send these global fields in argument of this method and as second argument I want to send value for this field.
I tried with object, generic type but I don't know how to do that. Here is example:
private void setName(String _name) {
if(isNull(_name)) {
this.name = "";
} else {
this.name = _name.toString();
}
}
And a few other methods use the same code but with other fields and argument and I want to do something like that:
private void setField(some_field, _value) {
if(isNull(_value)) {
this.some_field = "";
} else {
this.some_field = _value;
}
}
Could someone help?
For example I have 2 global fields:
String name, int age.
For them I need to use the same code (if) and I want do it in one method. In this case I have to use global field as argument and as second argument use correct value for this field so instead:
this.name = argument;
this.age=argument;
use: globa_field_argument = argument;
Example:
setField( this.name, "Test" );
setField( this.age, 5 );

First off I would probably declare your global fields as 'public static'.
for example:
public static int myNumber = 10;
public static String myString = "foo";
Secondly you should have to pass your fields as an argument since you can access them inside the method itself.
When you redefine the fields anywhere in your code you will do this:
this.myNumber = newNumber;
this.myString = newString;

Related

How to override "="

I was looking into Haxe abstracts and was very interested in building an abstract that would wrap a class and unify it to, in my case, an Int.
#:forward()
abstract Abs(Op)
{
public inline function new(value:Int = 0, name:String = "unnamed" )
{
this = new Op();
this.value = value;
this.name = name;
}
#:to
private inline function toInt():Int
{
return this.value;
}
}
class Op
{
public var value:Int = 0;
public var name:String = "no name";
public function new()
{
}
}
The problem I ran in to is when defining a #:from method - it has to be static and can take only one parameter - a new value. So whenever I set the abstract's instance value from the #:from method I will have to create a new instance of the abstract, thus resetting all the variables.
Basically what I'm talking about is this:
var a = new Abs(5, "my abs"); // value is 5; name is "my abs"
a = 100; // value is 100; name is reset to "unnamed" but I want it to be preserved
As much as I could find out we cannot overload the = operator in abstracts other than through implicit casting with a #:from method and I haven't found a way to really achieve this with macros.
If you have any ideas on how this can be done, please provide a minimalist example.
It depends what you want to do, but if you use this:
var a = new Abs(5, "my abs");
var myInt:Int = a;
It will use the abstract Abs.toInt function.
#:to
private inline function toInt():Int
{
return this.value;
}
The other way around also works:
var million = 1000000;
var myAbs:Abs = million;
It will use the static Abs.fromInt function.
#:from
static inline function fromInt(value:Int)
{
return new Abs(value, "what");
}
This is because it uses the implicit cast. http://haxe.org/manual/types-abstract-implicit-casts.html
Try it yourself: http://try.haxe.org/#Ae1a8
Is that what you are looking for?

Are accessors / mutators auto-defined in Groovy?

In the section on handling Java Beans with Groovy of Groovy In Action, I found this script (slightly modified):
class Book{
String title
}
def groovyBook = new Book()
// explicit way
groovyBook.setTitle('What the heck, really ?')
println groovyBook.getTitle()
// short-hand way
groovyBook.title = 'I am so confused'
println groovyBook.title
There are no such methods in the class Book so how does that work ?
Yes, they are auto defined and calling book.title is actually calling book.getTitle()
See http://groovy.codehaus.org/Groovy+Beans
You can see this in action with the following script:
def debug( clazz ) {
println '----'
clazz.metaClass.methods.findAll { it.name.endsWith( 'Name' ) || it.name.endsWith( 'Age' ) }.each { println it }
}
class A {
String name
int age
}
debug( A )
// Prints
// public int A.getAge()
// public java.lang.String A.getName()
// public void A.setAge(int)
// public void A.setName(java.lang.String)
// Make name final
class B {
final String name
int age
}
debug( B )
// Prints
// public int B.getAge()
// public java.lang.String B.getName()
// public void B.setAge(int)
// Make name private
class C {
private String name
int age
}
debug( C )
// Prints
// public int C.getAge()
// public void C.setAge(int)
// Try protected
class D {
protected String name
int age
}
debug( D )
// Prints
// public int D.getAge()
// public void D.setAge(int)
// And public?
class E {
public String name
int age
}
debug( E )
// Prints
// public int E.getAge()
// public void E.setAge(int)
Several notes:
For all property fields(public ones only), there are autogenerated accesors.
Default visibility is public. So, you should use private/protected keyword to restrict accessor generation.
Inside an accessor there is direct field access. like this.#title
Inside a constructor you have direct access to! This may be unexpected.
For boolean values there are two getters with is and get prefixes.
Each method with such prefixes, even java ones are treated as accessor, and can be referenced in groovy using short syntax.
But sometimes, if you have ambiguous call there may be class cast exception.
Example code for 4-th point.
class A{
private int i = 0;
A(){
i = 4
println("Constructor has direct access. i = $i")
}
void setI(int val) { i = val; println("i is set to $i"); }
int getI(){i}
}
def a = new A() // Constructor has direct access. i = 4
a.i = 5 // i is set to 5
println a.i // 5
​
4-th note is important, if you have some logic in accessor, and want it to be applied every time you call it. So in constructor you should explicit call setI() method!
Example for 7
class A{
private int i = 0;
void setI(String val) { println("String version.")}
void setI(int val) { i = val; println("i is set to $i"); }
}
def a = new A()
a.i = 5 // i is set to 5
a.i = "1s5" // GroovyCastException: Cannot cast object '1s5' with class 'java.lang.String' to class 'int'
​
So, as I see property-like access uses first declared accessor, and don't support overloading. Maybe will be fixed later.
Groovy generates public accessor / mutator methods for fields when and only when there is no access modifier present. For fields declared as public, private or protected no getters and setters will be created.
For fields declared as final only accessors will be created.
All that applies for static fields analogously.

How to display the ToString of an object which is in a ListBox?

I have a class which holds the string I want to display and an id for that item.
ref class ListBoxItem {
private:
int id;
String ^ name;
public:
ListBoxItem(int id, const char * name) { this->id = id; this->name = gcnew System::String(name); }
virtual String ^ ToString() new { return name; }
};
And I add each item to the ListBox like this:
for(list<string>::iterator i = listItems.begin(); i != listItems.end(); i++)
listBoxItems->Items->Add(gcnew ListBoxItem(2, (*i).c_str()));
This will produce a ListBox with the correct number of items, but all the items are called "ListBoxItem".
Instead, I want the ListBox to display the string which is produced when the ToString method is invoked on ListBoxItem.
You didn't say whether you were using WinForms or WPF, but I believe this answer is valid for either.
(Note: There is a class named ListBoxItem in the framework. You might want to pick a different class name.)
I believe the issue is here:
virtual String ^ ToString() new { return name; }
^^^
This means you're creating a brand new ToString method, which doesn't have anything to do with the Object.ToString method. When the ListBox calls ToString, it doesn't have your class definition, so it just calls Object.ToString(), which you haven't changed.
Switch it to this, and you should be good:
virtual String ^ ToString() override { return name; }
^^^^^^^^

AS3 - target variable using another variable string value

okay. so i have a function and i've passed a parameter through it called objectName.
no i have no idea how to do this or explain it. so here goes.
public function moveObject(ObjectName):void{
//objectName now holds "myName" which is an object also
//i would now like my variable called myNamePosition to equal 10
//so it would need to grab the value of objectName which is myName:Object.
//turn it into a string of some kind - myName:string
//add "Position" to the end of it so its myNamePosition
// make it equal to 10
trace(myNamePosition);
}
The functions parameters passed through would change so i cant actually use "myName". but rather "objectName".
Thanks
Example:
package
{
import flash.display.MovieClip;
public class astest extends MovieClip
{
public function astest()
{
init();
}
private var myNamePosition:int;
private function init():void
{
moveObject({myName:{}})
}
public function moveObject(objectName:Object):void
{
var propName:String;
for(propName in objectName)
break;
trace(propName);
propName+="Position";
trace(propName);
this[propName] = 10;
var propValue:* = this[propName];
trace(propValue);
}
}
}
output:
myName
myNamePosition
10
Is it what you need?

Overloading a method which accepts `object` as default parameter type

I need to be able to call a method and pass in an object of an unknown type
but then have the correct overload called. I also need a default implementation that accepts
object as its parameter type. What I'm seeing is that the default overload is the only one that ever gets used.
Here's the gist of what I'm trying to do:
class Formatter
{
private object Value;
public Formatter(object val){
Value = val;
}
public override string ToString()
{
return Format(Value);
}
private string Format(object value)
{
return value.ToString();
}
private string Format(DateTime value)
{
return value.ToString("yyyyMMdd");
}
}
Ok, so far so good. Now I want to be able to do this:
public static class FancyStringBuilder()
{
public static string BuildTheString()
{
var stringFormatter = new Formatter("hello world");
var dateFormatter = new Formatter(DateTime.Now);
return String.Format("{0} {1}", stringFormatter, dateFormatter);
}
}
The result of FancyStringBuilder.BuildTheString() is "hello world 2012-12-21 00:00:00.000", when I expected "hello world 20121221"
The problem is that the overload that accepts a DateTime is not being called, instead defaulting to the overload which accepts an object. How can I call the proper method without resorting to a messy switch statement?
In Formatter.ToString(), the override Formatter.Format(object) is always called. This is because the overload resolution happens at compile-time, not run-time. At compile-time, the only thing known about Value is that it's an object.
If you really want to distinguish incoming types, you'll need to do so in Formatter's constructor. In this case, rather than hanging on to the object, you could just call ToString() immediately and only store the formatted result:
class Formatter
{
string formattedValue;
public Formatter(object value)
{
formattedValue = value.ToString();
}
public Formatter(DateTime value)
{
formattedValue = value.ToString("yyyyMMdd");
}
public string ToString()
{
return formattedValue;
}
}
Note that this does assume that your object isn't changing between the time you create the Formatter object and the time Formatter.ToString() is called, or at the very least that it's okay to take a snapshot of the string representation at the time the Formatter is created.
This also assumes that you know the incoming types at compile-time. If you want a truly run-time-only solution, you'll have to use the "is" operator or a typeof() comparison.
If your goal is just to provide custom ToString() formatting based on the incoming type, I'd probably do it using a list that maps from types to format strings:
static class Formatter
{
private static List<Tuple<Type, string>> Formats;
static Formatter()
{
Formats = new List<Tuple<Type, string>>();
// Add formats from most-specific to least-specific type.
// The format string from the first type found that matches
// the incoming object (see Format()) will be used.
AddMapping(typeof(DateTime), "yyyyMMdd");
// AddMapping(typeof(...), "...");
}
private static void AddMapping(Type type, string format)
{
Formats.Add(new Tuple<Type, string>(type, format));
}
public static string Format(object value)
{
foreach (var t in Formats)
{
// If we find a type that 'value' can be assigned to
// (either the same type, a base type, or an interface),
// consider it a match, and use the format string.
if (t.Item1.IsAssignableFrom(value.GetType()))
{
return string.Format(t.Item2, value);
}
}
// If we didn't find anything, use the default ToString()...
return value.ToString();
}
}
With that, calling code then looks like:
Console.WriteLine(
"{0} {1}",
Formatter.Format(DateTime.Now),
Formatter.Format("banana"));
I think this is because the class constructor takes an object as parameter, and then assign that object to variable Value which is also an object. There for calling Format(object) since Value is of type object
Try this
public override string ToString()
{
if(Value is DateTime)
return Format(Convert.ToDateTime(Value)); //this should call the right method
return Format(Value); //works for other non-custom-format types e.g. String
}

Resources