Tuesday, February 8, 2011

How do I profile a Perl web app?

I am working on a web app that uses Perl and I need to look into speeding up portions of the app.

I thought I'd start profiling the particular calls for the portion I wish to investigate. I've done some searching on profiling Perl code, but unfortunately most of what I find says that I should run my perl code with -d:DProf myapp from the command line. That doesn't quite work for me since my code is within a web app. I did find a way to get the profiling to work with apache, but unfortunately, the "most used" modules that came back from the profiler were all CPAN modules -- Class::xyz, etc etc etc. Not terribly helpful.

Does anyone know of a good way besides me injecting "timer" code into the methods I wish to profile to target just these methods? I've thought of writing a test script and profiling that but due to the nature of the code I'm working on that would require a bit more work than I'm hoping to have to do.

  • You can use the Benchmark core module with the :hireswallclock option if you really want to time things internally. But really, you should be able to profile from the command line. You might have to write test scripts to emulate certain portions of a CGI request, but DProf can be extremely useful when looking for performance bottlenecks.

    In particular, look for where your code is calling the CPAN module code. You may be doing this in loops far more than necessary, so while the time is spent in the CPAN module, refactoring your code can fix the problem.

  • Have you tried Devel::NYTProf (much better than Devel::DProf), which can work under Apache? Which webserver are you using? Is this a vanilla CGI script, a mod_perl thing, or something else?

    The real trick, however, is to organize the code so that you can do the full spectrum of testing and profiling without having to put it all together at the end to find out something is slow. That won't help you much in the short term to fight fires, but it does prevent things from becoming fires in the long run. There are also various ways to fake the webserver environment and so on, but that's a different question. :)

    Leanan : Yeah, that's the one I tried, and all it turned up was all the cpan modules. I want to actually target these specific methods and see where they themselves are spending most of the time.
    mpeters : Which CPAN modules did it list? If you're doing a lot of database calls then it's quite possible that DBI and DBD modules will be at the top of your list. This isn't because Perl is doing too much work, but because your DB queries are slow. Start profiling them instead.
  • If you're using CGI.pm, you can pass arguments to your perl script on the command line and CGI.pm will interpret them as if they were passed as parameters over HTTP. So if you're debugging, e.g.

    http://example.com/scripts/example.pl?action=browse&search=grommet&restrict=blah

    then you could just call from the command line, e.g.

    perl -d:NYTProf documentroot/scripts/example.pl 'action=browse&search=grommet&restrict=blah'

  • I realize it's a bit late for it at this point, but this is one of the reasons why it's good to use CGI::Application or another architecture in which the web app is just a very brief bit of web-facing code which makes use of a bunch of modules you've written to implement the actual functionality. Using such a design makes it very straightforward to profile (or simply test) any modules from the command line, either individually or collectively, without having to worry about the web aspect.

TDD. When you can move on?

When doing TDD, how to tell "that's enough tests for this class / feature"?

I.e. when could you tell that you completed testing all edge cases?

  • Well, when you can't think of any more failure cases that doesn't work as intended.

    Part of TDD is to keep a list of things you want to implement, and problems with your current implementation... so when that list runs out, you are essentially done....

    And remember, you can always go back and add tests when you discover bugs or new issues with the implementation.

    From Mike Stone
  • You could always use a test coverage tool like EMMA (http://emma.sourceforge.net/) or its Eclipse plugin EclEmma (http://www.eclemma.org/) or the like. Some developers believe that 100% test coverage is a worthy goal; others disagree.

    From Jim Kiley
  • that common sense, there no perfect answer. TDD goal is to remove fear, if you feel confident you tested it well enough go on...

    Just don't forget that if you find a bug later on, write a test first to reproduce the bug, then correct it, so you will prevent future change to break it again!

    Some people complain when they don't have X percent of coverage.... some test are useless, and 100% coverage does not mean you test everything that can make your code break, only the fact it wont break for the way you used it!

    From pmlarocque
  • With Test Driven Development, you’ll write a test before you write the code it tests. Once you’re written the code and the test passes, then it’s time to write another test. If you follow TDD correctly, you’ve written enough tests once you’re code does all that is required.

    As for edge cases, let's take an example such as validating a parameter in a method. Before you add the parameter to you code, you create tests which verify the code will handle each case correctly. Then you can add the parameter and associated logic, and ensure the tests pass. If you think up more edge cases, then more tests can be added.

    By taking it one step at a time, you won't have to worry about edge cases when you've finished writing your code, because you'll have already written the tests for them all. Of course, there's always human error, and you may miss something... When that situation occurs, it's time to add another test and then fix the code.

  • Just try to come up with every way within reason that you could cause something to fail. Null values, values out of range, etc. Once you can't easily come up with anything, just continue on to something else.

    If down the road you ever find a new bug or come up with a way, add the test.

    It is not about code coverage. That is a dangerous metric, because code is "covered" long before it is "tested well".

  • On some level, it's a gut feeling of

    "Am I confident that the tests will catch all the problems I can think of now?"

    On another level, you've already got a set of user or system requirements that must be met, so you could stop there.

    While I do use code coverage to tell me if I didn't follow my TDD process and to find code that can be removed, I would not count code coverage as a useful way to know when to stop. Your code coverage could be 100%, but if you forgot to include a requirement, well, then you're not really done, are you.

    Perhaps a misconception about TDD is that you have to know everything up front to test. This is misguided because the tests that result from the TDD process are like a breadcrumb trail. You know what has been tested in the past, and can guide you to an extent, but it won't tell you what to do next.

    I think TDD could be thought of as an evolutionary process. That is, you start with your initial design and it's set of tests. As your code gets battered in production, you add more tests, and code that makes those tests pass. Each time you add a test here, and a test there, you're also doing TDD, and it doesn't cost all that much. You didn't know those cases existed when you wrote your first set of tests, but you gained the knowledge now, and can check for those problems at the touch of a button. This is the great power of TDD, and one reason why I advocate for it so much.

    From casademora
  • maybe i missed something somewhere in the Agile/XP world, but my understanding of the process was that the developer and the customer specify the tests as part of the Feature. This allows the test cases to substitute for more formal requirements documentation, helps identify the use-cases for the feature, etc. So you're done testing and coding when all of these tests pass...plus any more edge cases that you think of along the way

  • Alberto Savoia says that "if all your tests pass, chances are that your test are not good enough". I think that it is a good way to think about tests: ask if you are doing edge cases, pass some unexpected parameter and so on. A good way to improve the quality of your tests is work with a pair - specially a tester - and get help about more test cases. Pair with testers is good because they have a different point of view.

    Of course, you could use some tool to do mutation tests and get more confidence from your tests. I have used Jester and it improve both my tests and the way that I wrote them. Consider to use something like it.

    Kind Regards

  • Theoretically you should cover all possible input combinations and test that the output is correct but sometimes it's just not worth it.

  • Many of the other comments have hit the nail on the head. Do you feel confident about the code you have written given your test coverage? As your code evolves do your tests still adequately cover it? Do your tests capture the intended behaviour and functionality for the component under test?

    There must be a happy medium. As you add more and more test cases your tests may become brittle as what is considered an edge case continuously changes. Following many of the earlier suggestions it can be very helpful to get everything you can think of up front and then adding new tests as the software grows. This kind of organic grow can help your tests grow without all the effort up front.

    I am not going to lie but I often get lazy when going back to write additional tests. I might miss that property that contains 0 code or the default constructor that I do not care about. Sometimes not being completely anal about the process can save you time n areas that are less then critical (the 100% code coverage myth).

    You have to remember that the end goal is to get a top notch product out the door and not kill yourself testing. If you have that gut feeling like you are missing something then chances are you are have and that you need to add more tests.

    Good luck and happy coding.

    From smaclell
  • A test is a way of precisely describing something you want. Adding a test expands the scope of what you want, or adds details of what you want.

    If you can't think of anything more that you want, or any refinements to what you want, then move on to something else. You can always come back later.

    From jml
  • Tests in TDD are about covering the specification, in fact they can be a substitute for a specification. In TDD, tests are not about covering the code. They ensure the code covers the specification, because the code will fail a test if it doesn't cover the specification. Any extra code you have doesn't matter.

    So you have enough tests when the tests look like they describe all the expectations that you or the stakeholders have.

    From Cade Roux
  • Kent Beck's advice is to write tests until fear turns into boredom. That is, until you're no longer afraid that anything will break, assuming you start with an appropriate level of fear.

Why won't Visual Studio 2005 generate an Xml Serialization assembly?

Why isn't Visual Studio 2005 generating a serialization setting when I set the project setting "Generate Serialization Assembly" to "On"?

  • It turns out that Dev Studio only honors this setting for Web Services.

    For non-web services you can get this to work by adding an AfterBuild target to your project file:

      <Target Name="AfterBuild" DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource" Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)"  Outputs="$(OutputPath)$(_SGenDllName)">         
          <SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(OutputPath)"  References="@(ReferencePath)" ShouldGenerateSerializer="true" UseProxyTypes="false" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="$(SGenToolPath)">
              <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
          </SGen>
      </Target>
    

    See also:

    flipdoubt : +1 for this help, Adam! As a follow up question, is adding the SGen task to a project considered a best or worst practice? I'm hoping that it speeds up the performance of my app.
    From Adam Tegen
  • It can be done manually with sgen.exe.

    From Adam Tegen
  • Hey Adam, nice answer. Can you figure out a way to use the SGen MSBuild task and pass it the /f parameter to force the recreation of the serialization assembly after it is built? I would use the sgen.exe as a post-build event, but I can't find an environment variable for its path that is valid in the post-build event. Any ideas?

    From flipdoubt

Whiteboard Interview Questions

I teach a software engineering lab class for Seniors in Computer Science and Engineering (Bachelor's degree). I understand that many companies have interviewees solve simple programming problems on a whiteboard or piece of paper.

I would like to prepare my students for this as they do not normally have to stand in front of a judgmental audience and write programs on a whiteboard. Thus, I am looking for some good questions to ask them.

The question should be answerable in 15-30 minutes, on a whiteboard, by a solid CSE graduate. I am looking for programming questions, not puzzles.

  • Write a function which counts the number of vowels and consonants in a string. Any language you choose.

    dacracot : Trick is not to forget upper and lower, non-letters, and finally a null string.
    Mez : I'd use a regex to substitute the letters, then split it into an array, and get the occurences of my strings :D
    mike511 : what about sometimes "Y"? :)
    From dacracot
  • Write pseudo-code that would sort an array using several different algorithms.

    Adam Davis : Probably not a 15 minute board question, though. Maybe just bubble sort.
    From Dan Cramer
  • Classic c style string questions:

    1. implement strstr,strrchr, strpbrk, strlen functions and all other string manipulation: Contains, Replace, etc... Performance wise.

    2. implement strtok. Implement it as thread safe.

    Knowing pointers is a basic test. Experienced programmer should be able to do it within 15 minutes.

  • There are quite a few sites dedicated to this. e.g., http://www.techinterviews.com/. Most of them have puzzle questions, but they also have real technical questions as well. I'd check out those if you want a big list. There are hundreds of good questions in lots of different areas.

    From Derek Park
  • After years of trying various approaches to this problem in job interviews, I have settled on what I think is the best challenge:

    strstr: find the first location of a string in another string.

    This is a well-known function across many languages, and can be coded in under fifteen lines. (Anything more is too much for a whiteboard.)

    strstr is also perfect because it is just the right level of difficulty: two levels of looping. It sounds like it might be too easy, but it will instantly separate those who can code from those who cannot. In fact, maybe only one in five candidates gets it right without help.

    From adum
  • Implement a simple FIFO (queue) and LIFO (stack).

    Implement a priority queue.

    Implement a simple linked list.

    Implement a whitespace stripping function - removes leading and/or trailing whitespace from a byte array.

    Implement a function to convert a positive number into its hexadecimal equivalent, and then the converse.

    Implement atoi.

    Write a some code which demonstrates limitations of floating point code.

    Write a string compare routine in a recursive function.

    Derek Park : Adam, a stack is not a type of queue. Queues are FIFOs.
    Adam Davis : Not all queues are fifos - a priority queue is still a queue, but is not a fifo. You are correct that stacks are not queues, which is a mistake on my part. Fixed the text. Did someone downvote this just for that one error? Wow, strict types we've got around here!
    Derek Park : Your text is still confusing. A stack is a LIFO. A queue is not. The standard queue is a FIFO. Priority queues are different from standard queues, and are still not LIFOs.
    Adam Davis : Doh! I edited incorrectly! My bad...
    From Adam Davis
  • A good one I've used before is a simple question that reveals code reading skills, knowledge of binary, inductive reasoning skills, and communication skills (as the answer is probably not obvious, and questions are encouraged)

    What useful question does the following function answer about a number? Yes, it is a useful and distinct quality for a number to have, especially so in computer science. (Please tell them to ask questions and walk themselves through their thought process on the whiteboard)

    bool mystery(unsigned int num){
        unsigned int other = num - 1;
        bool result = ((num & other) == 0);
        return result;
    }
    

    The answer will be in a comment to this post.

    Sufian : This function answers the question: Is this number a power of two? (Bonus points if they realize it is incorrect for the input number 0)
    From Sufian
  • I tend to ask questions that should be solvable within a few minutes so that there is time for Q&A on their implementation. One question I like to ask is:

    Write a function that counts the number of bits in a list of integers.

    I'm often surprised on how many people have trouble with this.

  • One I use a lot is to write a function that reverses the words in a sentence, excluding punctuation. There are several variations on this by allowing/not allowing built-in methods for string manipulation.

    So, the sentence "The quick brown fox" becomes "fox brown quick The".

    The more important part of these excercises is to see/hear how the interviewee reasons out the solution. There is usually more than one way to solve the problem none of which are "more right" than any others.

  • For OO languages:

    Implement a money class that:

    • Doesn't suffer from precision loss (big numbers = bad juju in floating point)
    • Stores money internally in US dollars
    • Implements methods that return the value of money in Euros, Yen, Pounds, etc

    Implement a roman numeral class (accepts roman numeral strings or integers, stores the number, returns integer or roman numerals, doesn't have to be perfect (say only for numbers up to C)

    From Adam Davis
  • Having your students create simple functions on a whiteboard is good practice however I have noticed (at least for the company I work for) when we interview someone the problems they need to solve are much more involved.

    The main goal really for us is to see someones approach to an overall problem and how they solved it. For example:

    1. Implement or design a data base structure for a simple login application
    2. Given an xml structure, design classes and parsers to consume and manipulate the xml

    All not very difficult problems to solve but they help the interviewer learn how the interviewee approaches a problem, cause once the interviewee has finished the problems or has attempted them, we would discuss their design and approach.

    Just food for thought, possibly a good exercise would be to have them explain their approach to solving the problem once they have finished. This also gives them a chance to rethink about the problem while they are explaining it and helps reinforce good communication skills.

    From JustFoo
  • The first time I had to do whiteboard coding in an interview I totally flubbed it. My experience was that I was completely unprepared to write (compilable!) code on a blackboard without practice, and any kind of practice would've been an immense help.

    Anything simple,a few loop iterations. The important thing is to make it compilable.

    From Steve B.
  • Write pseudocode and the sketch of a design for a search engine. What are the parts of the system? How do you define success? What are the different phases of operation?

    You can deep-dive into any part of this thing to see if the person answering the question has the chops.

    From djsadinoff
  • Implement Twitter or iGoogle from scratch, go. (an idea from @rex-m)

  • The number one way I eliminate candidates is by very basic SQL experience. To that end I ask a couple of what should be simple SQL questions.

    1. requires them to know how to do a simple select statement with a where clause.
    2. requires them to do an inner (and outer) join on two tables
    3. requires them to update records with a where clause.

    Unfortunately, 90% of the so called application programmers out there can't do those queries. I can understand an embedded systems dev not knowing them, but anyone with a modicum of experience doing client / server or web apps should be able to answer them quickly.

    Also, I don't even care about exact syntax, as long as they understand the idea.

  • Here are some I've been asked in interviews:

    Write a function that does integer division without using / or %.

    Given two nodes in a binary search tree sketch a function that finds their least common ancestor.

    "Programming Pearls" by Jon Bentley is a great resource for these types of puzzles. Also "Programming Interviews Exposed" is a good resource.

    From MrDatabase
  • You may want to try a few problems from Project Euler they're fairly math oriented, but they can be quite challenging and rewarding.

  • Implement a binary search (presuming a sorted input).

    Most people get it wrong the first couple times through - I only ever use an already-written and -verified binary search because I get it wrong usually the first two times, too :)

    FM : +1 Just conducted a half dozens interviews. None of the candidates answered the question smoothly. *"Although the basic idea of binary search is comparatively straightforward, the details can be surprisingly tricky."* — Donald Knuth.
    warren : @FM - in 'Programming Pearls 2d ed', the author notes there was an error in the first edition with regards to binary search - and he is a pro :)
    From warren

How to check if a file has the win2003 "blocked" option on it.

How do I check from within my NSIS installer if my installer has the blocked option in preferences on it.

Even if you know of a way to check this without NSIS, please let me know so I can script it myself.

See this question to find out more info about this blocked option.

Code review addin for Visual Studio

This isn't so much as a question, as an idea which I think would be helpful. I decided to post it here to get feedback on the idea. I'm not sure if this isn't exactly the right place to post it, but I wanted to see what you guys think.

My idea is to create an code checkin policy which displays a diff of each modified file. To be able to check it in, another programmer has to 'sign off' on it; this is done via the other programmer using either Active Directory authentication, or just putting in a username and password from a random database. Obviously, a user wouldn't be able to sign off on his own code.

Ideally, it could be mixed with the sample from Microsoft which applies a checkin policy only to specific files, or to ignore small changes, and so on.

Or, is there already such a third-party policy?

  • I'm not sure about the policy location storage or whether a "user" has control over the "admin" or project managers' code settings, but DevPartner Studio is one of the most complete code review and analysis tools I have come across. It might be worth a try.

    http://www.compuware.com/products/devpartner/studio.htm

  • Have you evaluated TeamReview? It's not exactly what you're asking for but it's an Add-in that facilitates a rich code review experience in the IDE. Because it uses Team System work items the "approval" aspect your asking for is the completion of those items. Regular Team System reports and queries can be used to make sure the work is "signed off."

    Also - you might consider using the Source Control Annotate feature of Visual Studio Team System, Attrice's Code Review Side Kick, as well as the Code Review Workflow project on code plex

    TraumaPony : I'm not looking for such a thing; I was wondering if people thought it was a good idea.
    From JB Brown

Does Class need to implement IEnumerable to use Foreach

This is in C#, I have a class that I am using from some else's DLL. It does not implement IEnumerable but has 2 methods that pass back a IEnumerator. Is there a way I can use a foreach loop on these. The class I am using is sealed.

  • foreach does not require IEnumerable, contrary to popular belief. All it requires is a method GetEnumerator that returns any object that has the method MoveNext and the get-property Current with the appropriate signatures.

    /EDIT: In your case, however, you're out of luck. You can trivially wrap your object, however, to make it enumerable:

    class EnumerableWrapper {
        private readonly TheObjectType obj;
    
        public EnumerableWrapper(TheObjectType obj) {
            this.obj = obj;
        }
    
        public IEnumerator<YourType> GetEnumerator() {
            return obj.TheMethodReturningTheIEnumerator();
        }
    }
    
    // Called like this:
    
    foreach (var xyz in new EnumerableWrapper(yourObj))
        …;
    

    /EDIT: The following method, proposed by several people, does not work if the method returns an IEnumerator:

    foreach (var yz in yourObj.MethodA())
        …;
    
  • You could always wrap it, and as an aside to be "foreachable" you only need to have a method called "GetEnumerator" with the proper signature.

    
    class EnumerableAdapter
    {
      ExternalSillyClass _target;
    
      public EnumerableAdapter(ExternalSillyClass target)
      {
        _target = target;
      }
    
      public IEnumerable GetEnumerator(){ return _target.SomeMethodThatGivesAnEnumerator(); }
    
    }
    
  • Not strictly. As long as the class has the required GetEnumerator, MoveNext, Reset, and Current members, it will work with foreach

  • If foreach doesn't require an explicit interface contract, does it find GetEnumerator using reflection?

    Yuck.

    David B : Not run-time reflection... The compiler does the finding.
    From FlySwat
  • Given class X with methods A and B that both return IEnumerable, you could use a foreach on the class like this:

    foreach (object y in X.A())
    {
        //...
    }
    
    // or
    
    foreach (object y in X.B())
    {
       //...
    }
    

    Presumably the meaning for the enumerables returned by A and B are well-defined.

    Konrad Rudolph : This isn't what was asked: the methods return `IEnumerator`, not `IEnumerable`.
    Joel Coehoorn : D'oh! Parser error :o
  • No, you don't and you don't even need an GetEnumerator method, e.g.:

    class Counter
    {
        public IEnumerable<int> Count(int max)
        {
            int i = 0;
            while (i <= max)
            {
                yield return i;
                i++;
            }
            yield break;
        }
    }
    

    which is called this way:

    Counter cnt = new Counter();
    
    foreach (var i in cnt.Count(6))
    {
        Console.WriteLine(i);
    }
    
    Hallgrim : IEnumerable has a GetEnumerator method. This is the one that gets called when you do foreach.
    From pb
  • According to MSDN:

    foreach (type identifier in expression) statement
    

    where expression is:

    Object collection or array expression. The type of the collection element must be convertible to the identifier type. Do not use an expression that evaluates to null. Evaluates to a type that implements IEnumerable or a type that declares a GetEnumerator method. In the latter case, GetEnumerator should either return a type that implements IEnumerator or declares all the methods defined in IEnumerator.

    chris : RTFM! What a great concept. +1
  • Re: If foreach doesn't require an explicit interface contract, does it find GetEnumerator using reflection?

    (I can't comment since I don't have a high enough reputation.)

    If you're implying runtime reflection then no. It does it all compiletime, another lesser known fact is that it also check to see if the returned object that might Implement IEnumerator is disposable.

    To see this in action consider this (runnable) snippet.

    
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace ConsoleApplication3
    {
        class FakeIterator
        {
            int _count;
    
            public FakeIterator(int count)
            {
                _count = count;
            }
            public string Current { get { return "Hello World!"; } }
            public bool MoveNext()
            {
                if(_count-- > 0)
                    return true;
                return false;
            }
        }
    
        class FakeCollection
        {
            public FakeIterator GetEnumerator() { return new FakeIterator(3); }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                foreach (string value in new FakeCollection())
                    Console.WriteLine(value);
            }
        }
    }
    
  • Short answer:

    You need a class with a method named GetEnumerator, which returns the IEnumerator you already have. Achieve this with a simple wrapper:

    class ForeachWrapper
    {
      private IEnumerator _enumerator;
    
      public ForeachWrapper(Func<IEnumerator> enumerator)
      {
        _enumerator = enumerator;
      }
    
      public IEnumerator GetEnumerator()
      {
        return _enumerator();
      }
    }
    

    Usage:

    foreach (var element in new ForeachWrapper(x => myClass.MyEnumerator()))
    {
      ...
    }
    

    From the C# Language Specification:

    The compile-time processing of a foreach statement first determines the collection type, enumerator type and element type of the expression. This determination proceeds as follows:

    • If the type X of expression is an array type then there is an implicit reference conversion from X to the System.Collections.IEnumerable interface (since System.Array implements this interface). The collection type is the System.Collections.IEnumerable interface, the enumerator type is the System.Collections.IEnumerator interface and the element type is the element type of the array type X.

    • Otherwise, determine whether the type X has an appropriate GetEnumerator method:

      • Perform member lookup on the type X with identifier GetEnumerator and no type arguments. If the member lookup does not produce a match, or it produces an ambiguity, or produces a match that is not a method group, check for an enumerable interface as described below. It is recommended that a warning be issued if member lookup produces anything except a method group or no match.

      • Perform overload resolution using the resulting method group and an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.

      • If the return type E of the GetEnumerator method is not a class, struct or interface type, an error is produced and no further steps are taken.

      • Member lookup is performed on E with the identifier Current and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a public instance property that permits reading, an error is produced and no further steps are taken.

      • Member lookup is performed on E with the identifier MoveNext and no type arguments. If the member lookup produces no match, the result is an error, or the result is anything except a method group, an error is produced and no further steps are taken.

      • Overload resolution is performed on the method group with an empty argument list. If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, or its return type is not bool, an error is produced and no further steps are taken.

      • The collection type is X, the enumerator type is E, and the element type is the type of the Current property.

    • Otherwise, check for an enumerable interface:

      • If there is exactly one type T such that there is an implicit conversion from X to the interface System.Collections.Generic.IEnumerable, then the collection type is this interface, the enumerator type is the interface System.Collections.Generic.IEnumerator, and the element type is T.

      • Otherwise, if there is more than one such type T, then an error is produced and no further steps are taken.

      • Otherwise, if there is an implicit conversion from X to the System.Collections.IEnumerable interface, then the collection type is this interface, the enumerator type is the interface System.Collections.IEnumerator, and the element type is object.

      • Otherwise, an error is produced and no further steps are taken.

    From VVS
  • @Brian: Not sure you try to loop over the value return from method call or the class itself, If what you want is the class then by make it an array you can use with foreach.

    From c.sokun
  • For a class to be usable with foeach all it needs to do is have a public method that returns and IEnumerator named GetEnumerator(), that's it:

    Take the following class, it doesn't implement IEnumerable or IEnumerator :

    public class Foo
    {
        private int[] _someInts = { 1, 2, 3, 4, 5, 6 };
        public IEnumerator GetEnumerator()
        {
            foreach (var item in _someInts)
            {
                yield return item;
            }
        }
    }
    

    alternatively the GetEnumerator() method could be written:

        public IEnumerator GetEnumerator()
        {
            return _someInts.GetEnumerator();
        }
    

    When used in a foreach ( Note that the no wrapper is used, just a class instance ):

        foreach (int item in new Foo())
        {
            Console.Write("{0,2}",item);
        }
    

    prints:

    1 2 3 4 5 6

    Jon Skeet : It doesn't need to return an IEnumerator - just a type with the right members.

Tool to optimize C# using statements?

Is there any tool out there that can identify name spaces in the Using statement that are not needed and eliminate them from the source?

  • Resharper

  • Visual Studio 2008 does this, and I believe that Refactor Pro from DevExpress (as Consolidate Usings) has this as a refactoring.

  • The Visual Studio Power Pack will do it ofr the whole project at once. There's also a way to enable it in VS2005 via the registry.

  • Resharper, Refactor Pro!, Visual Studio 2008 now does this.

    In VS2008 if you right click in the text of the file and choose the option Organize usings then select one of the options. It will remove and or sort the using statements.

    PowerCommands for Visual Studio also does this.

    MikeJ : thank you. I guess I have put off installing vs 2008 long enough.
    MikeJ : this is great. thanks to everyone who took the time to help me out.
  • Code Rush with Refactor Pro does this. There is a light weight version of this built into Visual Studio 2008 which should do it for you. Highlight the namespaces and then right click them, then click refactor, and there should be an option to remove or re-order the usings.

  • Visual Studio 2008 PowerCommands can do this for a file at a time, or for an entire solution at once.

    From Kyralessa

Generic logging of function parameters in exception handling

A lot of my C# code follows this pattern:

void foo(string param1, string param2, string param3)
{
    try
    {
         // do something...
    }
    catch(Exception ex)
    {
        LogError(String.Format("Error in foo(param1={0}, param2={1}, param3={2}), exception={3}", param1, param2, param3, ex.Message));
    }
}

Is there a way in .NET to get a Key/Value list of the parameters to a function so that I can call another function to construct my error logging string? OR Do you have a more generic / better way of doing this?

  • When I have done this I just created a generic dictionary for the logging.

    I have this LogArgs class. And logging in a base class that I call when I have an exception.

    public class LogArgs
    {
    
        public string MethodName { get; set; }
        public string ClassName { get; set; }
        public Dictionary<string, object> Paramters { get; set; }
    
    
        public LogArgs()
        {
            this.Paramters = new Dictionary<string, object>();
        }
    
    }
    

    Then at the start of every method I do

    LogArgs args = new LogArgs { ClassName = "ClassName", MethodName = "MethodName" };
    args.Paramters.Add("Param1", param1);
    args.Paramters.Add("Param2", param2);
    args.Paramters.Add("Param3", param3);
    
    base.Logger.MethodStartLog(args);
    

    When I have an error I log it this way.

    base.Logger.LogError(args, ex);
    
  • No there isn't a way to do this.

    The normal practice is to not catch exceptions unless you can handle them.

    I.e. you would normally only catch exceptions and log them in a top-level exception handler. You will then get a stack trace, but won't of course get details of all the parameters of all method calls in the stack.

    Obviously when debugging you want as much detail as possible. Other ways to achieve this are:

    • Use Debug.Assert statements liberally to test assumptions you are making.

    • Instrument your application with logging that can be activate selectively. I use Log4Net, but there are also other alternatives, including using the System.Diagnostics.Trace class.

    In any case, if you do catch exceptions only to log them (I'd do this at a tier boundary in an n-tier application, so that exceptions are logged on the server), then you should always rethrow them:

    try
    {
        ...
    }
    catch(Exception ex)
    {
        log(ex);
        throw;
    }
    
    From Joe
  • You could use a similar style of constructing the message, but add the params keyword in your LogError method to handle the arguments. For example:

        public void LogError(string message, params object[] parameters)
        {
            if (parameters.Length > 0)
                LogError(string.Format(message, parameters));
            else
                LogError(message);
        }
    
    From JoshL
  • You could use Reflection and the convention that you must pass the parameters to the LogError with the right order:

    private static void MyMethod(string s, int x, int y)
    {
        try
        {
            throw new NotImplementedException();
        }
        catch (Exception ex)
        {
            LogError(MethodBase.GetCurrentMethod(), ex, s, x, y);
        }
    }
    
    private static void LogError(MethodBase method, Exception ex, params object[] values)
    {
        ParameterInfo[] parms = method.GetParameters();
        object[] namevalues = new object[2 * parms.Length];
    
        string msg = "Error in " + method.Name + "(";
        for (int i = 0, j = 0; i < parms.Length; i++, j += 2)
        {
            msg += "{" + j + "}={" + (j + 1) + "}, ";
            namevalues[j] = parms[i].Name;
            if (i < values.Length) namevalues[j + 1] = values[i];
        }
        msg += "exception=" + ex.Message + ")";
        Console.WriteLine(string.Format(msg, namevalues));
    }
    
    From Panos
  • You could use aspect oriented programming with PostSharp (have a look at http://www.postsharp.org, and the tutorial at http://www.codeproject.com/KB/cs/ps-custom-attributes-1.aspx). Basically you could do something like this:

    public class LogExceptionAttribute : OnExceptionAspect
    {
     public override void OnException(MethodExecutionEventArgs eventArgs)
     {
      log.error("Exception occurred in method {0}", eventArgs); 
     }
    }
    
    [LoggingOnExceptionAspect]
    public foo(int number, string word, Person customer)
    {
       \\ ... something here throws an exception
    }
    

    Perhaps not quite what you want, but I'm sure it can be adapted to suit your needs.

    From Jacob

VBScript: Using a variable within a DOM element

Hello all, I'm looking to use a VBScript variable within a reference to a DOM element for a web-app I'm building. Here's a brief exerpt of the affected area of code:

dim num
num = CInt(document.myform.i.value)
dim x
x = 0
dim orders(num)
For x = 0 To num
    orders(x) = document.getElementById("order" & x).value
    objFile.writeLine(orders(x))
Next

This is my first venture into VBScript, and I've not been able to find any methods of performing this type of action online. As you can see in the above code, I'm trying to create an array (orders). This array can have any number of values, but that number will be specified in document.myform.i.value. So the For loop cycles through all text inputs with an ID of order+x (ie, order0, order1, order2, order3, order4, etc. up to num)

It seems to be a problem with my orders(x) line, I don't think it recognizes what I mean by getElementById("order" & x), and I'm not sure exactly how to do such a thing. Anyone have any suggestions? It would be much appreciated!

  • I can only assume that this is client side VBScript as document.getElementById() isn't accessible from the server.

    try objFile.writeLine("order" & x), then check the source to make sure all the elements are in the document.

    [As I can't put code in comments...] That is strange. It looks to me like everything should be working.

    Only other thing I can think of is: change

    orders(x) = document.getElementById("order" & x).value
    objFile.writeLine(orders(x))
    

    to

    orders(x) = document.getElementById("order" & x)
    objFile.writeLine(orders(x).value)
    
    Dan Williams : You're right, it's just to help debug the problem. Making sure you're actually going through all the elements in the document. Have you tested what document.myform.i.value is returning?
  • It looks as if you're mixing client vs server-side code.

    objFile.writeLine(orders(x))
    

    That is VBScript to write to a file, which you can only do on the server.

    document.getElementById
    

    This is client-size code that is usually executed in JavaScript. You can use VBScript on IE on the client, but rarely does anyone do this.

    On the server you'd usually refer to form fields that were part of a form tag, not DOM elements, (assuming you're using classic ASP) using request("formFieldName").

    To make server-side stuff appear on the client (when you build a page) you'd embed it in your HTML like this:

    <% = myVariable %>
    

    or like this (as part of a code block):

    document.write myVariable
    
    From Diodeus
  • I was able to get this working. Thanks to both of you for your time and input. Here is what solved it for me:

    Rather than using

    document.getElementById("order" & x).value
    

    I set the entire ID as a variable:

    temp = "order" & x
    document.getElementById(temp).value
    

    It seems to be working as expected. Again, many thanks for the time and effort on this!

  • Don't you need to change your loop slightly?

    For x = 0 To num - 1
    

    E.G. With 4 items you need to iterate from 0 to 3.

  • hi who can make me a overflow style on a site... i want to overflow is a music playlist... can u make me a overflow playlist that when i move up the its goes up and when i move down the page it move down to... i will just send you the code if you send me a message that you are willing to do it for me send the code to my email.. heres my e-add jeric_magante@yahoo.com tnx

Assembly.Load and Environment.CurrentDirectory

I realize there is a somewhat related thread on this here: http://stackoverflow.com/questions/22012/loading-assemblies-and-its-dependencies

But I am modifying something and this doesn't exactly apply.

string path = Path.GetDirectoryName( pathOfAssembly ); 
Environment.CurrentDirectory = path;
Assembly.Load(Path.GetFileNameWithoutExtension(pastOfAssembly));

Is there any really reason you would do it like this? Wouldn't it make more sense to just use:

Assembly.LoadFile(pathOfAssembly);

Any insight would be greatly appreciated.

  • Looks like the "Department of Redundancy Department."

    A lot more code than is necessary. Less is more!

    Edit: On second thought, it could be that the assembly you are loading has dependencies that live in its own folder that may be required to use the first assembly.

    Adam Driscoll : This is exactly why they did it...thanks
    benPearce : If this answer is correct, maybe a vote for it?
    From benPearce
  • This can be necessary when you are developping a windows service. The working dir of a service defaults to %WinDir%, so if you want to load an assembly from the dir that your service exe resides in, this is the way to go.

    From Treb

Encrypting Source Code

I work on relatively sensitive code that we wouldn't want falling into the wrong hands. Up until now, all the code has been keep in house so it hasn't been an issue. I am moving to working from home a day or two a week and we want to secure the code on my laptop.

We have looked at a few alternatives, but Windows EFS and Bitlocker seem to be the most obvious. The laptop doesn't have TPM hardware, and I won't have access to Active Directory from home, so EFS looks to be the option.

Basically, does anyone else have any alternatives, or issues with using EFS to encrypt source code?

  • The last time I did this was a few years ago, but we used PGPdisk. It did a good job.

    From nsayer
  • Truecrypt

    hangy : Agreed. An encrypted TrueCrypt partition should also be fast enough not to slow down compilation process etc..
    Sunny : Just be sure to place the page file also on that partition.
    Martin Beckett : You can also set windows to clear the pagefile on shutdown instead.
  • You should look into TrueCrypt. It's free, open source and supported on a number of platforms.

    From QAZ
  • You should consider using truecrypt. It would accomplish the same thing, and be a bit less invasive to your system.

  • I would also recommend Truecrypt

    From PostMan
  • TrueCrypt, there's no excuse to use anything different. It's secure and it's free...what more could you want.

  • +1 for TrueCrypt. We use it at work, it's great.

    Tip: it seems that if you have a big codebase and you work with multiple working copies checked out simultaneously, you get much better performance if each working copy is on its own encrypted partition.