I am using director class for scene transitions and i need to use the variable in a class in another class. So how can i call it?
local a= require "welcome"
variableName is text display object in welcome class
print(a.variableName.text)
However i get nil.
Could you help me out? Thanks
Make the variable a property of the returned table:
local Class = {}
function Class.new()
local class = {}
class.variableName = display.newText("Hello mom!", 100, 100, "Helvetica", 18)
return class
end
return Class
Then you can reference it:
local a = require ("class").new()
print(a.variableName.text)
OR
If you want to pass variables between the screens in Rauber's Director Class, you can:
local parameters = {p1="some text", p2="some more text"}
director:changeScene(parameters, "sceneName")
In your screen, make the new function accept the parameters:
function new(parameters)
print(parameters.p1, parameters.p2) --> some text some more text
end
OR
Put _G in front of your variable
_G.myGlobalVar = "some awesome stuff"
Then you can reference it in another class
print(_G.myGlobalVar) --> some awesome stuff
Related
I'm wondering if there a way to pass a value which I receive after constructor and put in in constructor options. The problem is that I also have a value from constructor which I need to pass, so it has dependencies from both sides.
class Test
constructor: (#opt={}) ->
#opt.width = obj.width
#opt.color = "#f45
# obj.width is undefined
obj = new Obj
width: 200
color: #opt.color
Or my real example.
class Button extends Layer
constructor: (#opt={}) ->
super _.defaults #opt,
width: #btnText.width
type: "default"
# btnText.width is undefined
#btnText = new Text
width: 200
type: #opt.type
How can I solve this problem and get rid of undefined values? Might be I can use some sort of await and promise? Don't know :-)
Thank you in advance!
I have already asked a question here where I basically require an instance of a base class to be converted into a subclass (or a new instance of the subclass to be created using the instance of the base class' properties). The conclusion seems to be that the best way to do this is to manually assign every property I need to transfer in the constructor of the base class.
While this is feasible in some cases, it certainly is not when there are many properties to transfer, or when the base class is subject to change — every time you add a property to the base class, the constructor needs to be changed too, so this solutions is inelegant.
I have searched online, and can't see any reason for why this kind of type-casting isn't implemented. The arguments I have seen so far describe this operation to 'not make any sense' (making a minivan from a car was an analogy I saw), question what to do about the non-inherited variables in the subclass, or claim that there must be some better solution for what was trying to be achieved.
As far as I can see, the operation doesn't need to 'make sense' as long as it's useful, so that isn't much of a good reason. What's wrong with adding a few more properties (and perhaps methods/overriding them) to change an instance into a subclass? In the case of the non-inherited variables, that can simply be solved by allowing this kind of type-cast only a constructor is added to the subclass or by just simply setting them to their default values. After all, constructors usually call MyBase.New(...) anyway. What's the difference between using the constructor of the base (essentially creating a new instance of the base) and using an instance which is already initialised? Lastly, I don't think the third argument is well-justified — there are times when all of the other solutions are inelegant.
So finally, is there any other reason for why this kind of casting isn't allowed, and is there an elegant way to circumvent this?
Edit:
Since I don't know a lot about this topic, I think I meant to say 'convert' rather than 'cast'. I'll also add an example to show what I'm trying to succeed. The conversion would only be allowed at the initialisation of the Subclass:
Class BaseClass
Dim x as Integer
Dim y as Integer
End Class
Class Subclass1 : Inherits BaseClass
Dim z as Integer
Sub New(Byval value As Integer)
'Standard initialisation method
MyBase.New()
z = value
End Sub
Sub New(Byval value As Integer, Byval baseInstance As BaseClass)
'Type conversion from base class to subclass
baseInstance.passAllproperties()
'This assigns all properties of baseInstance belonging to BaseClass to Me.
'Properties not in BaseClass (eg. if baseInstance is Subclass2) are ignored.
z = value
End Sub
End Class
Class Subclass2 : Inherits BaseClass
Dim v As Integer
End Class
What you describe is not casting. Have you ever heard the expression"to cast something in a different light"? It means to look at the same thing in a different way or to make the same thing look different. That is the exact way that the term "cast" is used in programming. When you cast, you do NOT change the type of the object but only the type of the reference used to access the object. If you want to cast from a base type to a derived type then the object you're referring to has to actually be that derived type. If it's not then you're not performing a cast but rather a conversion.
So, why can't you convert an instance of a base type to an instance of a derived type. Well, why would you be able to? Yes, it's something that might save writing a bit of code on occasion but does it actually make sense? Let's say that you have a base type with one property and a derived type that adds another property. Let's also say that that derived type has constructors that require you to provide a value for that second property. You're suggesting that the language should provide you with a way to magically convert an instance of the base class into an instance of the derived class, which would mean it would have to slow you to circumvent that rule defined by the author via the constructors. Why would that be a good thing?
Use System.Reflection to iterate over properties and fields of the base class and apply them to the derived class. This example includes a single public property and single public field, but will also work with multiple private/protected properties and fields. You can paste the entire example into a new console application to test it.
Imports System.Reflection
Module Module1
Sub Main()
Dim p As New Parent
p.Property1 = "abc"
p.Field1 = "def"
Dim c = New Child(p)
Console.WriteLine("Property1 = ""{0}"", Field1 = ""{1}""", c.Property1, c.Field1)
Console.ReadLine()
End Sub
Class Parent
Public Property Property1 As String = "not set"
Public Property Field1 As String = "not set"
End Class
Class Child
Inherits Parent
Public Sub New(myParent As Parent)
Dim fieldInfo = GetType(Parent).GetFields(BindingFlags.NonPublic _
Or BindingFlags.Instance)
For Each field In fieldInfo
field.SetValue(Me, field.GetValue(myParent))
Next
Dim propertyInfo = GetType(Parent).GetProperties(BindingFlags.NonPublic _
Or BindingFlags.Instance)
For Each prop In propertyInfo
prop.SetValue(Me, prop.GetValue(myParent))
Next
End Sub
End Class
End Module
Output:
Property1 = "abc", Field1 = "def"
This solution is automated, so you won't need to change anything when adding or removing properties and fields in the base class.
In general, because of this:
Class TheBase
End Class
Class Derived1 : TheBase
Sub Foo()
End Sub
End Class
Class Derived2 : TheBase
Sub Bar()
End Sub
End Class
Sub Main()
Dim myDerived1 As New Derived1
' cast derived to base
Dim myTheBase = CType(myDerived1, TheBase)
' cast base to derived?
' but myTheBase is actually a Derived1
Dim myDerived2 As Derived2 = CType(myTheBase, Derived2)
' which function call would you like to succeed?
myDerived2.Foo()
myDerived2.Bar()
End Sub
How should I correctly create such a class which can be used from any .swift-file of my project and does not need to be initialized with a variable?
I mean that I want not to have to write something like
someVar = myClass()
in each file where I want this class to be usable. I just want this class to have a global public variables and change them from a .swift-file of my project by doing something like
myClass.myVar = value
I'm thinking about making this class a separate file. What's a correct way to do this?
You can create a static property inside a class or struct and call it anywhere. E.g:
//Config.swift
struct Config
{
static var field1 : String = "Field_Value"
static var field2 : String = "Field_Value"
}
You can use the property calling StructName.propertyName.
E.g:
//MyCode.swift
print(Config.field1)
Config.field1 = "New Value"
You can create a new class, make a variable off that class outside any class.
Class Awesome{
}
let awesomeness = Awesome()
you can than use 'awesomeness' as class instance in every other swift file
I am learning python tkiner from a reference book. The examples are coded in plain style, i.e., not in class format. I want to learn coding in classes because I think it helps manage long codes.
I am trying to make the text widget (named textPad) accessible to a helper function inside a class called TextEditor. The job of the helper function is to select all the text which I type. However, as soon as I run the script, I get global error that the textPad is not defined. Even when I add self. to textPad, i.e., self.textPad, I get an attribute error that Class object has no attribute textPad. The code is part of an excercise to make a full functional text editor. Below, I provide the core code which generates the error. What is the wrong with this code?
Could you please clarify my doubts: where is the best place to define helper functions: inside class or outside class? In both cases, how to make them accessable?
from tkinter import *
class TextEditor():
def __init__(self, root):
self.select_all() #helper function declare
myMenu = Menu(root, tearoff=0) #Menu bar
editMenu = Menu(root, tearoff)
editMenu.add_command(label="Select All", accelerator="Ctrl+A", command=select_all)
myMenu.add_cascade(label="Edit", menu=editMenu)
root.config(menu=myMenu)
textPad = Text(root, wrap="word", undo=True)
textPad.pack(expand="yes", fill="both")
def select_all(self):
textPad.tag_add('sel', '1.0', 'end')
if __name__ == '__main__':
root=Tk()
app = TextEditor(root)
root.mainloop()
This is the error:
Traceback (most recent call last):
File "C:\Python33\gui\tkguibook\textpad.py", line 21, in <module>
app = TextEditor(root)
File "C:\Python33\gui\tkguibook\textpad.py", line 6, in __init__
self.select_all() #helper function declare
File "C:\Python33\gui\tkguibook\textpad.py", line 17, in select_all
textPad.tag_add('sel', '1.0', 'end')
NameError: global name 'textPad' is not defined
Thank you in advance for your kind help!
First of all, I advise you to watch some tutorials on object-oriented paradigm in Python without using tkinter directly.
The problem with your code is that textPad is not a property of the class, but it's a simple local variable to the __init__ method or constructor. To make it a property, you should use self to declare and then refer to the just declared property.
For example, suppose I have the following class:
class TextEditor:
def __init__(self):
# stuff
and you want to add a property, visible in all the points in your class, you can do it in this way:
class TextEditor:
def __init__(self):
self.textPad = tkinter.Text() # using 'self' to declare a property
now, if you want to refer to that property in another method, you should use always the self:
class TextEditor:
def __init__(self):
self.textPad = tkinter.Text()
def set_text(self, new_text):
self.textPad.insert(tkinter.END, "hello") # using 'self' to refer to the property
To know more about self.
I have a custom class module in VBA (Access) that is supposed to handle a large amount of external data. Currently I have two functions Read(name) and Write(name, value) that allows to read and set dynamic properties.
Is there a way to define a more syntactic way to read and write those data? I know that some objects in VBA have a special way of accessing data, for example the RecordSet, which allows to read and set data using myRS!property_name. Is there a way to do exactly the same for custom class modules?
The exclamation mark syntax is used to access members of a Scripting.Dictionary instance(you'll need to add a reference to Microsoft Scripting Runtime through Tools > References first). To use this syntaxyou'll need to be storing the information internally in a dictionary.
The quickest way to use it in a class is to give your class an object variable of type Scripting.Dictionary and set it up as follows:
Option Explicit
Dim d As Scripting.Dictionary
Private Sub Class_Initialize()
Set d = New Scripting.Dictionary
End Sub
Private Sub Class_Terminate()
Set d = Nothing
End Sub
Public Property Get IntData() As Scripting.Dictionary
Set IntData = d
End Property
Now you can access properties using myinstance.IntData!MyProperty = 1... but to get to where you want to be you need to use Charlie Pearson's technique for making IntData the default member for your class.
Once that's done, you can use the following syntax:
Dim m As MyClass
Set m = New MyClass
Debug.Print "Age = " & m!Age ' prints: Age =
m!Age = 27
Debug.Print "Age = " & m!Age ' prints: Age = 27
Set m = Nothing
Okay, thanks to Alain and KyleNZ I have now found a working way to do this, without having a collection or enumerable object below.
Basically, thanks to the name of the ! operator, I found out, that access via the bang/pling operator is equivalent to accessing the default member of an object. If the property Value is the default member of my class module, then there are three equivalent statements to access that property:
obj.Value("param")
obj("param")
obj!param
So to make a short syntax working for a custom class module, all one has to do is to define a default member. For example, I now used the following Value property:
Property Get Value(name As String) As String
Value = SomeLookupInMyXMLDocument(name)
End Property
Property Let Value(name As String, val As String) As String
SetSomeNodeValueInMyXMLDocument(name, val)
End Property
Normally, you could now access that like this:
obj.Value("foo") = "New value"
MsgBox obj.Value("foo")
Now to make that property the default member, you have to add a line to the Property definition:
Attribute Value.VB_UserMemId = 0
So, I end up with this:
Property Get Value(name As String) As String
Attribute Value.VB_UserMemId = 0
Value = SomeLookupInMyXMLDocument(name)
End Property
Property Let Value(name As String, val As String) As String
Attribute Value.VB_UserMemId = 0
SetSomeNodeValueInMyXMLDocument(name, val)
End Property
And after that, this works and equivalent to the code shown above:
obj("foo") = "New value"
MsgBox obj("foo")
' As well as
obj!foo = "New value"
MsgBox obj!foo
' Or for more complex `name` entries (i.e. with invalid identifier symbols)
obj![foo] = "New value"
MsgBox obj![foo]
Note that you have to add the Attribute Value.VB_UserMemId = 0 in some other editor than the VBA editor that ships with Microsoft Office, as that one hides Attribute directives for some reason.. You can easily export the module, open it in notepad, add the directives, and import it back in the VBA editor. As long as you don't change too much with the default member, the directive should not be removed (just make sure you check from time to time in an external editor).
See this other question: Bang Notation and Dot Notation in VBA and MS-Access
The bang operator (!) is shorthand for
accessing members of a Collection or
other enumerable object
If you make your class extend the Collection class in VBA then you should be able to take advantage of those operators. In the following question is an example of a user who extended the collection class:
Extend Collections Class VBA