How to add method to System.Console class in Visual Basic - visual-studio-2010

I have little experience with Visual Basic.
I would like to add some methods to the System.Console class for a simple console application I am making. I am aware of the way to add extension methods to class. I've tried this code, but it gives the error: Reference to a non-shared member requires an object reference.
Imports System.Runtime.CompilerServices
Module Module1
<Extension()>
Public Sub WriteStuff(ByRef Console As System.Console, ByVal Output As String)
Console.Write(Output & "?")
End Sub
Sub Main()
Console.WriteStuff("Hello")
Console.ReadKey()
End Sub
End Module

Extension methods are instance methods; they cannot be applied statically. System.Console is a class, not an object, and methods like ReadKey() are static. Static extension methods are not allowed.
Look at your signature:
Public Sub WriteStuff(ByRef Console As System.Console, ...
It makes no sense to take a class identifier by reference, right (or at all for that matter)?

Related

If "puts" method is a private instance method, why can we call it from anywhere?

I have read that "puts" is a private instance method of the module Kernel (and therefore of Object, since Object mixes in Kernel).
That's why when we call puts, we don't specify a explicit receiver. My question is, if it's a private instance method, how is it possible that we can call it from any other scope? So, we can do:
class Test
puts "hello" # self is Test. So, we are calling self.puts "hello" -
end
What am I missing here? How is it possible that this works? We are calling a private instance method?
EDIT:
Same question arises if I do this:
class Object
private
def talk
puts "hi there"
end
end
class Test
talk # outputs 'hi there'
end
Why is it possible that from class Test we can call a private method from the class Object?
Please have a look at the doc for the Kernel module - http://www.ruby-doc.org/core-2.0.0/Kernel.html.
Unlike Java, Ruby is not limited to Classes as containers of implementations. Modules act as wonderful containers which can be mixed into other classes. When a module is mixed into another class, all its instance methods become instance methods of those class. Since the Kernel module is mixed into the Object class, its methods are therefore available in all Ruby classes.
Please read the following:
Ruby access control
Common misunderstanding and clarification about access controls in Ruby
With the risk of duplication, I have to say this: private in Ruby is not the same as in C++ or Java. Subclasses of a class can call private methods declared in their superclass. In fact, you can call private method of any class using :send. The only difference between private and protected methods is that private methods can't be called with explicit receivers.
Even the last rule has an exception. If your private method is something like age=, it can (and has to be) called with self. Funny, isn't it? :)
UPDATE: (to explain the gist):
The talk method which you wrote in your code above is being called on the main object which is the context for all Ruby programs. It's not being called on the Test class which is why it's not working for your second gist.
In the gist that I have provided, talk is a private class method which is why it gets executed at the time of class definition. In the same gist, the talk2 method is an instance method and can only be called from within instance methods. Your example gist didn't work because you were trying to invoke an instance method at the time of defining the class.
I don't understand why such long answer as in the other answer is required, or is upvoted. The answer to your question is simple.
It is because almost all classes (i.e., anything other than BasicObject) includes Kernel. Therefore, in the scope of a usual object, Kernel class is inherited, and hence its methods are accessible. That is all.

Can you use a base class to allow multiple derived classes to be passed as parameters to a function in VB6?

I've googled for articles on VB6's support for polymorphism, but all of the articles that I read merely mentioned that you can make a derived class inherit properties and methods from a derived class. None of the three or four articles that I read mentioned whether or not VB6's polymorphism allowed you to pass the derived classes as parameters of the base class type.
If you were to have a class named Bunny, which was derived from a class named Animal, could you pass a variable of type Bunny to the following function?
Public Sub Chase(thePerson as Person, theAnimal as Animal)
Do While thePerson.position <> theAnimal.position
...
Loop
End Sub
If your Bunny class Inherits from Animal then yes you should be able to do what you've stated in your sample code.

When should I use "class Object", "class Module", "module Kernel" and nothing?

I'm new to ruby metaprogramming, and I see people metaprogramming code in different places, like class Object, class Module, module Kernel and "nothing" (ie, out of a class/module definition block).
E.g.: I'm creating a c_attr_accessor method to access class variables, and I'm not sure where I must put the code, since it works in any of those cases.
How to decide what place is more appropriate to put a new global code?
Each of these examples fall into different cases.
If you are writing methods that apply to all objects, then you open the Object class so all objects can access it. If you are writing methods that apply to all modules, then you open Module. Whenever you open a class to add methods, the methods should apply to all instances of the class and nothing else.
Extending the Kernel module is different: people do this to add methods that should be available to every scope, but not really as methods to be explicitly called on an object, by making them private.
When you are outside of any class or module statement, you are in the scope of the main object, and methods you define default to being private methods of Object. This is fine for small or simple programs, but you will eventually want to use proper modules as namespaces to organize your methods.
As a final note on the subject, you always need to be sure that you really want methods you add to built-in classes and modules to be available to everything in your application, including external inclusions because they all share the built-ins.
Now to apply this to answer your question. Because you are defining a method that creates accessors for class variables, you should put it in the class Class as it applies to all classes and nothing else. Finally, you will likely only use it in class definitions (within a class statement), so we should make it private:
class Class
private
def c_attr_accessor(name)
# ...
end
end
class User
c_attr_accessor :class_variable_name
# ...
end
If you don't really need it in every class (maybe just a few), then create a "mixin module" to extend every class that needs this feature:
module ClassVariableAccessor
private
def c_attr_accessor(name)
# ...
end
end
class User
extend ClassVariableAccessor
c_attr_accessor :class_variable_name
# ...
end
Note that you are using Object#extend to add c_attr_accessor only to the object User (remember that classes are objects; you will hear that a lot if you are new to Ruby metaprogramming).
There is another way to implement the last example, which works by explicitly extending its base class through the Module#included(base_class) "hook method" called whenever the module included, and the base class is passed to base_class:
module ClassVariableAccessor
def included(base_class)
base_class.extend ClassMethods
end
module ClassMethods
def c_attr_accessor(name)
# ...
end
end
end
class User
include ClassVariableAccessor
c_attr_accessor :class_variable_name
# ...
end
I recommend this last solution because it is the most general and uses a simple interface that should not need to be updated. I hope this is not too much!
Have you tried looking up where the normal attribute accessors are defined? I'd either define it in the same class/module, or create my own module in which all my new methods go.

main vs initialize in Ruby

Okay, so I've looked through a couple of my ruby books and done some googling to no avail.
What is the difference between main and initialize in Ruby? I've seen code that uses
class Blahblah
def main
# some logic here
end
# more methods...
end
and then calls it using Blahblah.new.
Isn't new reserved only for
initialize? if not, then what's the difference between the two?
Class#new calls alloc on the class and then initialize on the created object. It does not call main.
The method name main has no special meaning in ruby's standard library. So unless you're inheriting from a class, which defines new or initialize in such a way, that main will be called, main will not be called automatically in any way.
See class Class
Look up class Class in your Ruby documentation.
You will find a public instance method called new.
All classes are instances of Class, so they all have a class method self.new. As it happens, this method calls allocate to create the class and then, if an initialize instance method is defined for the new class, it calls it, and forwards its (i.e., new's) arguments.
There isn't anything special about main.

vb6 :create object dynamically

In vb6, i can do :
set object=new class
where object is a Object and Class is a class defined in the code.
Now, i want to do the same dynamically, i want to do something like:
set object=createobject("class")
but it fail because createobject is apparently for activex registered class and not class modules.
If you put the class in question in a separate VB6 OCX, you will be able to use createObject to create them on-the-fly.
I hope the reason you want to do this is to mimic some sort of interface-like functionality, otherwise it's probably not an ideal solution.
Anyway, you could create a method that gives back a different class depending on the string you provide.
function myClassCreatingFunction(className)
select className
case: "Class1"
set myClassCreatingFunction = new Class1
exit function
...
end select
end function

Resources