Archive for August 4th, 2010
SSH, cygwin and domain users
Yes you can log in to your local computer via ssh with a domain account.
If it seems you can’t (i.e., your password is rejected) then you most likely need to export your user accounts and groups so cygwin can see them.
Another clue that you need to export is if you get a message like:
Your group is currently "mkpasswd". This indicates that the /etc/passwd (and possibly /etc/group) files should be rebuilt. See the man pages for mkpasswd and mkgroup then, for example, run mkpasswd -l [-d] > /etc/passwd mkgroup -l [-d] > /etc/group Note that the -d switch is necessary for domain users.
To export domain users:
$ mkpasswd -d >> /etc/passwd
To export groups:
$ mkgroup > /etc/group
Troubleshooting
Errors logging in as domain user
2 [main] -bash 31884 C:\cygwin\bin\bash.exe: *** fatal error - couldn't dynamically determine load address for 'WSAGetLastError' (handle 0xFFFFFFFF), Win32 error 126Connection to localhost closed.
This is because the cygwin sshd service must also run as domain account. I solved this by changing the user to my domain account.
Why can’t I hang an extension method on a type?
My brother asked me this. And while I don’t know, I did discover some interesting things along the way.
An extension method is nothing more than a compiler trick. It is simply a static method that takes an instance of the type being extended as an argument. That’s it.
The sugar part is that to you as a programmer, it appears to read more naturally in some cases.
They do not have any special privileges on private or protected members and they are not analagous to ruby module mixins (because the extended class cannot invoked extension methods).
[TBD: It is interesting that instance methods are supplied "this" as their first argument, see CIL]
[TBD: It is interesting that the compiler emits a callvirt instruction even in cases where call seems more appropriate just because callvirt has a null reference check. See: Why does C# always use callvirt?]
[TBD: Extensions are really a higher level abstraction because they operate only against public interface. An extension method is a client of the object it "extends"]
Example
namespace Examples {
public class ExampleClass { }
public static class Extensions {
public static void ExtensionMethod(this ExampleClass instance) {
instance.ToString();
}
}
public class ThatUsesExampleClass {
public void RunExample() {
new ExampleClass().ExtensionMethod();
}
}
}
The interesting part is RunExample (because it invokes the extension method):
public void RunExample() {
new ExampleClass().ExtensionMethod();
}
which compiles to:
.method public hidebysig instance void
RunExample() cil managed
{
// Code size 13 (0xd)
.maxstack 8
IL_0000: nop
IL_0001: newobj instance void Examples.ExampleClass::.ctor()
IL_0006: call void Examples.Extensions::ExtensionMethod(class Examples.ExampleClass)
IL_000b: nop
IL_000c: ret
} // end of method ThatUsesExampleClass::RunExample
It is clear that the compiler has done nothing more than redirect to a static method on a static class:
IL_0006: call void Examples.Extensions::ExtensionMethod(class Examples.ExampleClass)
Usage
The usual static method usage rules apply:
[Clean code chapter 6]
Procedural code (code using data structures) makes it easy to add new functions withoutchanging the existing data structures. OO code, on the other hand, makes it easy to add new classes without changing existing functions.The complement is also true:
Procedural code makes it hard to add new data structures because all the functions must
change. OO code makes it hard to add new functions because all the classes must change.
So, the things that are hard for OO are easy for procedures, and the things that are
hard for procedures are easy for OO!In any complex system there are going to be times when we want to add new data
types rather than new functions. For these cases objects and OO are most appropriate. On
the other hand, there will also be times when we’ll want to add new functions as opposed
to data types. In that case procedural code and data structures will be more appropriate.Mature programmers know that the idea that everything is an object is a myth. Sometimes
you really do want simple data structures with procedures operating on them.
Back to the question
Still no answer.
But I can’t see any reason why the C# compiler couldn’t do the same for static constructs, but I wonder how you would express that on the extension method itself. Perhaps that’s where the ExtensionAttribute comes in. Note: It currently is illegal to use the ExtensionAttribute directly.
But if you examine the IL for an extension method itself, you’ll see it has been applied:
.custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() =
( 01 00 00 00 )
.method public hidebysig static void
ExtensionMethod(class Examples.ExampleClass 'instance') cil managed {
.custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() =
( 01 00 00 00 )
// Code size 9 (0x9)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: callvirt instance string [mscorlib]System.Object::ToString()
IL_0007: pop
IL_0008: ret
} // end of method Extensions::ExtensionMethod
