This question already has answers here:
How do I create a class instance from a string name in ruby?
(4 answers)
Closed 4 years ago.
I need to create a class but the condition is, I will receive the class name in strings like shown below
["IndividualContact", "Legal"].each do |var|
ind = var.new
end
Now My expectation is, I need to call
IndividualContact.new and Legal.new but since var is a string variable, it's calling .new on a string like given below
"IndividualContact".new
rather than calling
IndividualContact.new
Is there any way can I call as I expected?
Use Module#const_get (assuming these classes are already defined in the global namespace):
%w|IndividualContact Legal|.map do |klazz|
Kernel.const_get(klazz).new
end
The code above will return an array containing two instances: one instance of IndividualContact and one of Legal.
Related
This question already has answers here:
Updating an attribute of an element in list with matching attribute
(2 answers)
Closed 4 years ago.
I would like to modify an attribute of an object in an Arraylist. For example :
class A {
String text;
boolean bool;
// getters and setters....
}
If I have an ArrayList<A> in an other class, how can I modify the attribute of a given String text (which is in an object in the ArrayList)
I know it's possible on java 8 with collections and stream but I can't figure how to do it
list.forEach(a -> a.setText("some new value"));
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm new in vb6 and not good at searching stuff. what is wrong with this code? I created form1 and inserted class module.
Private sub form_load()
call Jo.Display(txtdate.text)
end sub
in may Class module ClsJo
public function Display(txtdate as string)
txtdate = "123abc"
end function
The Display function has one parameter, txtdate, that is passed "by reference", which means that the function may change it's value. You are passing a value to that function, so I'm assuming you want the txtdate.Text property to contain the value "123abc" after the call.
However, this will not work as you have written it.
txtdate.Text is a property and properties are not really variables, they are kind of functions. You have "let" operator to set a property value and "get" operator to get the value of the property, but you don't have direct access to the actual variable that stores the value.
Therefore, when passed to the function, VB6 will get the value of the property, create a temporary variable from it and pass that temporary variable as the parameter to the function. The change in this temporary variable will never find it's way back to the txtdate.Text property.
To get the functionality that I think you want, you can do either one of these:
A. Create a variable yourself, pass that to the function and set the txtDate.Text property to the returned value. This would be my recommended method, because the function will have cleaner parameters. Like this:
Private Sub Form_Load()
Dim myText As String
myText = txtDate.Text
call Jo.Display(myText)
txtDate.Text = myText
End Sub
B: Pass the txtDate as parameter to the function, instead of the property, like this:
Public Sub Display(ByRef dateControl As Object)
dateControl.Text = "123abc"
End Function
Private Sub Form_Load()
Jo.Display txtDate
End Sub
How do i pass a variable to another class?
These two classes are not my main.
The variable I want to use in class1 is test which is int 5 from class2.
You Can make them public(or, eben better, use get set) and then you habe access to them.
public int Name;
I've been practicing some Ruby meta-programming recently, and was wondering about assigning anonymous classes to constants.
In Ruby, it is possible to create an anonymous class as follows:
anonymous_class = Class.new # => #<Class:0x007f9c5afb21d0>
New instances of this class can be created:
an_instance = anonymous_class.new # => #<#<Class:0x007f9c5afb21d0>:0x007f9c5afb0330>
Now, when the anonymous class is assigned to a constant, the class now has a proper name:
Foo = anonymous_class # => Foo
And the previously created instance is now also an instance of that class:
an_instance # => #<Foo:0x007f9c5afb0330>
My question: Is there a hook method for the moment when an anonymous class is assigned to a constant?
There are many hooks methods in Ruby, but I couldn't find this one.
Let's take a look at how constant assignment works internally. The code that follows is extracted from a source tarball of ruby-1.9.3-p0. First we look at the definition of the VM instruction setconstant (which is used to assign constants):
# /insns.def, line 239
DEFINE_INSN
setconstant
(ID id)
(VALUE val, VALUE cbase)
()
{
vm_check_if_namespace(cbase);
rb_const_set(cbase, id, val);
INC_VM_STATE_VERSION();
}
No chance to place a hook in vm_check_if_namespace or INC_VM_STATE_VERSION here. So we look at rb_const_set (variable.c:1886), the function that is called everytime a constant is assigned:
# /variable.c, line 1886
void
rb_const_set(VALUE klass, ID id, VALUE val)
{
rb_const_entry_t *ce;
VALUE visibility = CONST_PUBLIC;
# ...
check_before_mod_set(klass, id, val, "constant");
if (!RCLASS_CONST_TBL(klass)) {
RCLASS_CONST_TBL(klass) = st_init_numtable();
}
else {
# [snip], won't be called on first assignment
}
rb_vm_change_state();
ce = ALLOC(rb_const_entry_t);
ce->flag = (rb_const_flag_t)visibility;
ce->value = val;
st_insert(RCLASS_CONST_TBL(klass), (st_data_t)id, (st_data_t)ce);
}
I removed all the code that was not even called the first time a constant was assigned inside a module. I then looked into all the functions called by this one and didn't find a single point where we could place a hook from Ruby code. This means the hard truth is, unless I missed something, that there is no way to hook a constant assignment (at least in MRI).
Update
To clarify: The anonymous class does not magically get a new name as soon as it is assigned (as noted correctly in Andrew's answer). Rather, the constant name along with the object ID of the class is stored in Ruby's internal constant lookup table. If, after that, the name of the class is requested, it can now be resolved to a proper name (and not just Class:0xXXXXXXXX...).
So the best you can do to react to this assignment is to check the name of the class in a loop of a background worker thread until it is non-nil (which is a huge waste of resources, IMHO).
Anonymous classes don't actually get their name when they're assigned to a constant. They actually get it when they're next asked what their name is.
I'll try to find a reference for this. Edit: Can't find one, sorry.
Extract Method (a refactoring from Fowler's book) works great if your method doesn't assign any values. If it assigns one value, that becomes the return value of the extracted method. What if it assigns two values?
Some C# code to illustrate:
private void someBigFunction() {
doSomething();
doSomethingElse();
// start extraction here
string first = Database.Select(...);
// ...
// next is dependent on the value of "first"
int next = Database.Select(...);
// ...
// stop extraction here
doMoreUselessStuff();
}
The exact code or values are not important here. The point is extracting this method. (The two values are linked, so it makes sense to have them in the same method -- and not to make two methods.)
Possible answers to this question would be "return both in an array," "return them both in a pair-like data structure," or "use out parameters (pass by reference)" -- but I'm looking for something cleaner. (The actual code is in Delphi, not C#)
Perhaps Sprout Class is what you're looking for. Make the two members instance variables of a new class and extract this method into that class, assigning the instance variables and providing getters for the caller. Or, of course, you could convert the local variables to be instance variables of the original class. That conversion frequently makes Extract Method easier, but you wind up with what is arguably an excess of instance variables. With Sprout class, you have a class whose only purpose is to retrieve and provide those values, so there's no question that they deserve to be instance variables in it.