Wednesday, March 23, 2011

Locking a MySQL database so only one person at once can run a query?

I am having a few issues when people are trying to access a MySQL database and they are trying to update tables with the same information.

I have a webpage written using PHP. In this webpage is a query to check if certain data has been entered into the database. If the data hasn't, then i proceed to insert it. The trouble is that if two people try at the same time, the check might say the data has not been entered yet but when the insert takes place it has been by the other person.

What is the best way to handle this scenario? Can i lock the database to only process my queries first then anothers?

From stackoverflow
  • You're looking for LOCK.

    http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html

    This can be run as a simple mysql_query (or MySQLi::query/prepare).

    I'd say it's better to lock specific tables (although you can probably try LOCK TABLES *) that need to be locked rather than the whole database - as nothing will be able to be read. I think you're looking for something like:

    LOCK TABLES items;
    START TRANSACTION;
    INSERT INTO items (name, label) VALUES ('foo', 'bar');
    UNLOCK TABLES;
    

    Or in PHP:

    mysql_query('LOCK TABLES items');
    mysql_query("INSERT INTO items (name, label) VALUES ('foo', 'bar')");
    mysql_query('UNLOCK TABLES');
    
  • You could check if data has been changed before you edit something. In that case if someone has edited data while other person is doing his edit, he will be informed about it.

    Kind of like stackoverflow handles commenting.

  • Read up on database transactions. That's probably a better way to handle what you need than running LOCK TABLES.

  • Manually locking tables is the worst think you could ever do. What happens if the code to unlock them never runs (because the PHP fails, or the user next clicks the next step, walks away from the PC, etc).

    One way to minimize this in a web app, and a common mistake devs do, is to have a datagrid full of text boxes of data to edit, with a save button per row or on the whole table. Obviously if the person opens this on Friday and comes back Monday, the data could be wrong and they could be saving over new data. One easy way to fix this is to instead have EDIT buttons on each row, and clicking the button then loads an editing form, this way they are hopefully loading fresh data and can only submit 1 row change at a time.

    But even more importantly, you should include a datetime field as a hidden input box, and when they try to submit the data look at the date and decide how old the data is and make a decision how old is too old and to warn or deny the user about their action.

Arrays as result type and input for functions

in delphi7 i have a function that i need to return a array as a result type b

"function createsbox(key:tkey):array[0..255] of byte;" this is not allowed it is expecting a "identifyer expected but array found" is the error throw up. seems to work fine if i declare a record type of array but it seems pointless to do this for one function.

From stackoverflow
  • The issue is that you're not allowed to create a new type in a function declaration. But that's what you're doing when you specify the return type as array[0..255] of Byte. Instead, declare a named type, and then use it for the return type:

    type
      TSBox = array[0..255] of Byte;
    
    function CreateSBox(const Key: TKey): TSBox;
    

Session Variable problems when storing an object in my Session

I have a log in page where I valid my users and based on this validation I store their user info in a session variable so I can access it at any time. To do this I am trying to store an instance of one of my dbml generated classes "UserInfo". So I populate the class and then store it in a session variable I call "user"

 UserInfo u = new UserInfo();
    u = dal.RetrieveUser(userID, userPass)
    Session["user"] = u;

The issue I am having with this is it seems to mix up these session variables between users. Or more specifically it always seems to take the information from the first user variable stored for each subsequent user that logs in. So user 1's info is being pulled in for User 2, User 3, etc...

Is my problem that my class "UserInfo" is somehow static? Or what is causing this to happen? My UserInfo class looks like this:

public partial class UserInfo
    {
        ...

EDIT: After further review it seems that my Session variables are in fact working properly but my custom menus are actually the problem.

From stackoverflow
  • Sounds more like an issue with the DAL than the session object. Can you verify that the userID passed each time is different and the RetrieveUser function is using the passed value and not a static one?

    Collin Estes : yeah I checked it and made sure but it is retrieving the right information and creating the session variable correctly. The userID is actually just the value of the text box from the login.
  • Are you testing this using the web client on the same computer or separate computers? For instance, by default FireFox will run in a single process even if you have multiple windows or tabs open. As silly as it sounds, a colleague of mine had not noticed this phenomena when he had the same issue.

Cons for defining logger non-static

Comments for this answer http://stackoverflow.com/questions/212697/how-do-you-reduce-java-logging-boilerplate-code#212753 strongly suggest not to use loggers as instance member variables. I can think of two negative side-effects:
1) superclass logs with the subclass's logger
2) object cannot be serialized (unless marked transient)

But if serializing is not necessary and logging with subclass name is not a problem, is there anything else why it should be avoided? I think it reduces boilerplate code and avoids copy-paste errors while copying logger variable definition from one class to another. Even Spring framework (which I believe has very good coding standards) uses this method.

From stackoverflow
  • Try debugging an error where you see a message generated by the SuperClass class when the error is really being logged in the SubClass class. I've seen several situations where developers create a LoggingUtils class which generates messages which generally duplicate the things which are already baked-in by the logging framework.

    The only real situation I see for using a shared logging instance is something like the Apache commons HttpClient logger httpclient.wire which is shared between several classes for logging the contents of the requests and responses sent through the client. This particular logging situation does not log information for the actual implementation of the package, it logs information about the whole http "transaction".

  • Another, probably minor con: wasted memory, especially when you have lots of instances, each one with its own logger

    martsraits : Log4j (I presume other logging frameworks also) holds a pool of loggers. So only one instance with the same name is created. So memory consumption is the same as with static loggers.
    Ashutosh Singh : if this is con then better to use singelton
    Yoni Roit : @martsraits: No, because your class holds a new reference (pointer) to the pooled instance
  • The major difference asides from the Superclass logging with subclass name, of course, is that you'll have one Logger object per member of your class. Depending on how many classes are using logging, this can be a huge amount of Loggers, so memory bloat may be an issue.

    Plus from an abstract point of view, the logger really does belong to the class and can be shared between all instances, rather than each instance needing its own private copy, so it makes sense to declare it as static. Flipping your question around, what advantages does it have to making it non-static? (Being able to pass getClass() into the getLogger() call instead of passing in the class constant is the only thing I can think of, and that's such a tiny thing).

    martsraits : Log4j (I presume other logging frameworks also) holds a pool of loggers. So only one instance with the same name is created. So memory consumption is the same as with static loggers.
    martsraits : As a pro I also mentioned reducing boilerplate code.
  • If your Logger is an instance member instead of static, the Logger has to be retrieved every time a new object is created. Albeit this overhead is probably insignificant, but it's one disadvantage.

    From a design perspective, Loggers aren't really a property of an object, since they're usually meta-information about your system rather than business information within the system itself. A Logger isn't really part of something like a Car object in the same way an Engine or a Transmission is. Tying Loggers to objects as members (in most cases) doesn't make sense semantically more than anything.

If all my sql server database access is done thru stored procedures.....

If all my sql server database access is done thru stored procedures, and I plan on continuing that practice, is using linq2sql and/or the entity framework for future projects an unnecessary layer of complexity that doesn't add much value?

Related question: is Microsoft trying to steer developers away from relying on stored procs for data access?

From stackoverflow
  • No. LINQ2SQL adds a lot of value in terms of being able to easily map your database entities to classes in your code and work with those classes easily with native langugage constructs. You can easily map the CRUD operations of the generated entity class onto your stored procedures if you want. I do find that some things no longer require stored procedures to work easily and so I have moved away from using them, but you are not forced to. Essentially what LINQ2SQL can do is replace much, if not all, of your DAL, saving you from having to write this code.

    annakata : +1 both sprocs and linq offer more than just data access
  • LINQ-to-SQL supports mapping lots of operations (including CRUD) to stored procedures, but you lose composability - i.e. you can't just add (exp).Where(x=>x.IsActive). One option there is table-valued functions (UDFs) in place of stored procedures that query data; this also presents a more rigid meta model (rather than SET FMT_ONLY ON, which is hit'n'miss).

    That way, your query methods are composable at the database; but note that Entity Framework does not support this, even though LINQ-to-SQL does.

    tvanfosson : I'm using table-valued functions for things like search or browse with filtering. Pass in the filter parameters to the function, get back matching elements from the table. Drop on the table in the designer and I get a function that I can use to replace the data source for a bound control.
    tvanfosson : Actually, doing mostly MVC now, so the bound control thing is sort of moot, but you get the idea...
  • I use Linq2sql for calling my stored procedures as well just because its so fast to generate .net code I can call from my app, its just drag and drop, basically done in seconds. Still I think you need to ask yourself how much time you spend maintaing those stored procedures. If you do you would save a lot of time using linq2sql doing your crud calls. I use sprocs only when doing multiple step operations on the database.

  • Just to address your related question: The benefits of using stored procedures are not as prominent as they once were. Though I would not go as far as saying stored procedures are evil, as some have said in the past (http://www.tonymarston.net/php-mysql/stored-procedures-are-evil.html - this is a very nice article though), I would say that the use of dynamic sql, as long as it's done in a well defined structured way, is perfectly acceptable these days.

    I don't this Microsoft are trying to steer developers away from using stored procs but that dynamic sql should be seen as an acceptable option.

  • You lose the ability to write Linq queries, which is the best part of linq-to-sql.

Type Libraries in Delphi?

What is the best way to save a Delphi Type Library in SVN.

The file changes every time you compile the Application

The file is not saved in a readable form of AscII

It is very difficult to work out what changes have been made from one version to the next

This is a major problem when more than one person is changing the file

QUESTIONS:

1) Should one save an exported ‘IDL’ file in the version control ?

2) Can one covert an ‘IDL ’ into a Delphi type library If so how ?

3) What are the best practices when working with a Delphi type library ?

4) How easy is it get rid of the type library in Delphi2009 datasnap project?

p.s. I am using BDS2006

From stackoverflow
  • In Delphi 2009, this has changed completely. Type libraries are now saved in the project as plain text, RIDL files. These will play nice with source control. DataSnap is also completely changed; you can read about it here, and see a screencast here.

  • There are some good answers to this question at Delphi and COM: TLB and maintenance issues.

  • Prior to Delphi 2009, I would not check in the TLB file but manually put the TLB (and *_TLB.PAS file for reference) into a zip file then force that into version control. When ever I made actual changes to the TLB, I would update the zip file and check it in. The local TLB was always made read/write and ignored by the version control system. This scheme saved me several times when the TLB file would mysteriously no longer compile, I could just close my project, unzip from the zip file, reload the project and continue working.

where should I save a complex MVC application UI state?

I've been having a look at several MVC frameworks (like rails, merb, cakephp, codeignitier, and similars...)

All the samples I've seen are basically plain and simple CRUD pages, carrying all the infr needed in the querystring and the posted field values.

I've got a couple of apps made with some sort of framework built with classic asp.

This framework handles some CRUD stuff a little more complex than the examples I found.

Something like master-detail, filtering by example, paging, sorting and similars.

I have a controller class that it's just a finite state machine, that goes thru diferent states (like new, browse, filter, show, etc.), then performs the appropiate action depending on the event raised and finally retrieves the neede info to the calling page.

To achieve this I have several hidden inputs to keep the state of the web page (like current id, filter criterias, order criterias, previous state, previous event, well, you get the idea)

What do you think would be the finnest approach to achieve this kind of funcionality?

hidden inputs built in the view and used from the controller??? (I guess that would be the equivalent of what I'm doing right now in classi asp)

--

(added in response to tvanfosson)

basically, my question refers to the third category, the context-dependent setting (in respect to the other two categories I agree with you) the info I was storing in hidden fields to store them on the querystring, I guess that when you click on the "next page" you include everything you need to save in the querystring, right? so that piece of query string gets appended in each and every link that performns some kind of action...

I'm not sure, what are the advantages and disadvantages of using the querystring instead of hidden inputs???

From stackoverflow
  • I use different strategies depending on the character of the actual data. Things that are preferences, like default page size, I keep in a Preferences object (table) that is associated with the current logged in user and retrieve from there when needed.

    Persistent settings associated with the current logon, like filter settings for a page, are stored in the user's session. Generally these are things that if a user sets them in the current session they should remain sticky. I think filter settings and visibility are like this. If I filter a list, navigate away from it to drill down into a particular item, then come back to the list, I want my filter settings to be reapplied -- so I make it part of the session.

    Context-dependent settings -- like the current sort column or page number, are controlled using query parameters. Paging and sort controls (links) are built with the appropriate query parameters to "do the right thing" when clicked and pass any necessary query parameters to maintain or update the current context of the control. Using the query parameters allows you to use an HTTP GET, which is bookmarkable, rather than a POST. Using hidden form parameters makes it much harder for the user to save or enter a URL that takes them directly where they want to go. This is probably more useful for sorting than it is for paging, but the principle applies equally.

Addressing instance name string in __init__(self) in Python.

I am doing something like this:

class Class(object):
    def __init__(self):
        self.var=#new instance name string#

How do I make the __ init __ method of my instance to use the instance name string for 'c'? Say in case:

c=Class()

I want c.var equal to 'c'.

Thanks for your replies, I am implementing persistence and Class is persistent object's class. I want __ init __ to add an entry to the database when:

c=Class()

Then, suppose:

del c

Later on:

c=Class()

sholuld create an instance using data from database if there already is an entry 'c', otherwise create new entry.

From stackoverflow
  • That isn't possible. You seem to be confusing variables and objects.

    In any case there may well not be a variable:

    e.g.

    foo(Class())
    
    Class().arbitraryMethod()
    

    Or multiple:

    a = b = Class()
    
  • I am unaware of a way to access a variable's name programmatically without using deep reflection and a debugger. I do not think the information is available at runtime.

    If you want to give instances a (unique?) name, you should probably make the initializer accept an extra argument.

    def __init__(self, name):
        self.name = name
    

    And the caller should pass in the appropriate name:

    c = Class("c")
    
  • You can't (short of incredible hacks like examining the stack frame and inspecting the bytecode). There may not even be a name, or there could be multiple such names. What should be given for the following code fragments for instance:

    l = [Class(), Class()]
    a=b=c=d=Class()
    
  • I don't think this would be possible because the assignment to the variable of your new instance occours after the object is fully constructed and initialized and so you don't know the variable name it will be assigned to within init method

  • You can't do this. The reason for this is that the object of the class is created first, and only afterwards is this object bound to the name of the instance.

  • This is a scope issue, you can't do what you're asking. Because c would be declared outside your class' scope, your instance is unaware of what its been named in code.

    Perhaps if you can provide a broader explanation of what you're trying to accomplish a better solution can be suggested.

  • Python doesn't have variables, it has objects and names. When you do

    c = Class()
    

    you're doing two things:

    1. Creating a new object of type Class
    2. Binding the object to the name c in the current scope.

    The object you created doesn't have any concept of a "variable name" -- If later you do

    a = c
    

    then the same object is accessible in exactly the same way using the names a and c. You can delete the name a, and the object would still exist.

    If the objects you create need to have a name, the best way is to pass it to them explicitly,

    class Class(object):
        def __init__(self, name):
            self.name = name
    
    var = Class('var')
    
  • Thanks for your replies, I am implementing persistence and Class is persistent object's class. I want __ init __ to add an entry to the database when:

    c=Class()
    

    Then, suppose:

    del c
    

    Later on:

    c=Class()
    

    sholuld create an instance using data from database if there already is an entry 'c', otherwise create new entry.

    bobince : You would have to pass the 'c' (or other, more unique, identifier) in explicitly - probably better than doing it with magic anyway. There is magic that could detect bound names if you wrapped the whole thing up in a class with a metaclass, but it's definitely worse than just doing it manually here.
    S.Lott : This is not an answer. This is more of your question. Please update your question with these additional facts.
  • To persist data objects you need to use the database record's unique ID.

    pesudo code because I don't know what database module you're using

    import db # assume this is your db module
    
    class Class(object):
        def __init__(self):
            self.id = None
            self.name = None
    
        def get_by_id(self, id):
            records = db.execute('select * from table where id=%s' % str(id))
            if records:
                self.id = records[0]['id']
                self.name = records[0]['name']
    
        def save(self):
            db.execute('update table set name=%s where id=%s' % (self.name, str(self.id)))
    

    Again, this is pseudo code, the string injection technique I'm using is NOT advised as its fairly insecure, its just there to illustrate how to persist using classes with a db.

  • I have the same thought several years ago. This is somekind of neat feature, but the language creator doesn't provide it. And I thought they are all fool to not discover this great feature.

    But then come to think about that. I think the logic is impossible. say:

    class Class(object): def init(self): self.instance_name.move() # self.instance_name refer to var def move(self): print "move"

    var = Class()

    now if the var is an array is that possible too ?

    var[0] = Class() # i think it will get confused a bit

    that's what i think of, i don't think that assigning the instance into itself is possible. and in some language I just sent the instance string into the object then using eval to execute the function

Lambda variable names - to short name, or not to short name?

Typically, when I use lambdas, I just use "a, b, c, d..." as variable names as the types are easily inferred, and I find short names to be easier to read. Here is an example:

var someEnumerable = GetSomeEnumerable();
var somethingElseList = someEnumerable.Select(a => a.SomeProperty)
                                      .OrderBy(a => a.SomePropertyField);
var someDictionary = somethingElseList.ToDictionary(a => new SomeClass(a.Prop1),
                                                    a => a);

Some question this naming, and would prefer to see long typed out names, like this:

var someEnumerable = GetSomeEnumerable();
var somethingElseList = someEnumerable.Select(importantObj => importantObj.SomeProperty)
                                      .OrderBy(objsInfo => objsInfo.SomePropertyField);
var someDictionary = somethingElseList.ToDictionary(theInfoId => new SomeClass(theInfoId.Prop1),
                                                    theInfoId2 => theInfoId2);

Since the scope is so narrow (between the parens), unless you're getting stupid and nesting them, I find it easier to read short names.

Without getting caught up in the silly naming examples I used above, what is the general consensus on Lambda variable names? To short name, or not to short name?

From stackoverflow
  • I try to use single-word but meaningful names. So I would tend to use "person" rather than "p" but wouldn't go for "newlyAddedPerson".

    This goes for query expressions as well - I may well violate this in quick throwaway examples, but I don't generally like:

    from p in source
    where p.Age > 10
    select p.Name;
    

    I'd far rather see

    from person in source
    where person.Age > 10
    select person.Name;
    
    TheSoftwareJedi : yes, I tend to name better in expression syntax, but that's because the scope is wider, and can become confusing.
    TheSoftwareJedi : In expression syntax, I usually name longer names as the scope is wider. I don't see the point of writing .OrderBy(theInt => theInt) instead of .OrderBy(a => a).
    Jon Skeet : It makes it clearer what the element is at that point of the query. It's not always obvious, unfortunately.
  • I like the shortname thing. I do that all the time. I mostly use i,y,x in lambdas, but I use a,b,c,d in sql.

  • The way I usualy do it depends on the collection you're enumerating over. If the name of the collection implies what type the lambda parameter will be, then I just go with the single letter, however if the collection isn't as descriptive, then I'll use a word.

    IE:

    myCollection.Where(person =>....); //non descriptive collection name
    
    myPeopleCollection.Where(p=>...); // descriptive collection name
    
  • It may be asking a lot to ask a question for 'consensus' on 'naming'. :)

    I agree that 'the importance of a good name' is proportional to the scope of the name. Jon Skeet's answer of preferring

    from person in source ...
    

    is compelling, but if the name is used a lot and especially if the input is better named, I think I prefer

    from p in persons ...
    
    TheSoftwareJedi : I see questioning the naming in expression syntax as different than the naming in lambda syntax.
  • I'd say I agree with BFree. That, for me, it will depend on the context, but I always try to make it as 'concise' as possible. Notice I say concise, and not terse or short.

    Here's two examples in the LISP dialect Clojure:

    user=> (def names ["ryan" "bob" "tom" "tim"])
    #'user/names
    
    user=> (filter (fn [name] (.startsWith name "t")) names)
    ("tom" "tim")
    

    For those that don't know Lisp/Clojure, my lambda is the argument to the function 'filter'. That is, "(fn [name] ....)". I chose to use 'name' here because it's short but describes exactly what I'm working with. However, I think an 'a', 'i', 'x', etc would be just as readable.

    user=> (def odds (iterate (fn [n] (+ n 2)) 1))
    #'user/odds
    
    user=> (take 5 odds)
    (1 3 5 7 9)
    

    Here, I just use 'n' to stand for 'number'. I think 'number' would be OK too, but is slightly too verbose for my taste.

    I certainly would NOT use the names 'nameOfPerson' or 'previousOddNumber'. That's just WAY too much information. I also try to keep types out of my names most of the time, e.g. 'nameString'. I find stuff like that, most of the time, to be superfluous information.

    Personally, I think extra verbose names like that tend to stem from the idea that it helps document the code. It is especially prevalent in languages like Java/C# it seems. I think this could be argued both ways, depending on the programmer's style. However, the more verbose the name, the more tight (read brittle) the code can become. If my name is very specific, and it's a function changes often, then chances are the name will have to change a lot too. Eventually, the DEV might get lazy and you'll end up with a name that doesn't actually describe what the variable is used for. This is not a problem, if and only if the programmer doesn't assume the name is correct. Granted, this would probably be figured out quickly during compilation (because the programmer will try to divide two strings or some such thing), but it can cause wasted time and confusion in larger projects.

    I would also argue for conciseness because of screen real-estate. I still try to wrap my rows at 80 columns wide, and that's hard when 'myVaraibleNameIsAsLongAsAParagraph'.

    Ultimately, I think it's always going to come down to compromise. So they don't like 'a', but maybe they can agree that you should strive for one-word names like 'person' or 'number', and avoid that awful camel case.

    Sorry for the book.

    TheSoftwareJedi : +1 Thanks for the book
  • I go with one, two or three letters, which form an abbreviated representation of the object in question.

    Persons.Where(p => ...)
    AnalysisCode.Where(ac => ...)
    
  • As a general rule, I think the more explicit you are with variable/object/method names the better. Since we often spend most of our time reading other people's code, the easier it us to understand the faster you can get your focus off the syntax and onto the logic. These days with IntelliSense and the like, it's not really a burden to err on the side of clarity whenever possible.

Is there a way to remove private members from Content Assist in Eclipse

I'm in Eclipse writing Java. I come from Visual Studio with Resharper writing C#.

When Content Assist comes up, I see all the private members of a class, even though I'm not editing that class. Is there a way I can turn that off?

It's really distracting.

From stackoverflow
  • Window -> Preferences -> Java -> Editor ->Content Assist -> Hide proposals not visible in the invocation context

    ageektrapped : That doesn't seem to work for me. Others in the office said the same thing, and it works for them, but not for me.
    starblue : Strange. I've tested it before answering and it works for me, too (in Eclipse Ganymede).
  • If you do not explicitly write a method's access level (public, protected, or private), then it will default to package-private, and these methods will probably been shown in Content Assist.

Is the Silverlight 2 Bible worth purchasing?

Someone on SO mentioned they'd bought a copy and I'm damned if I can find the question again.

http://www.amazon.co.uk/Silverlight-2-Bible-Brad-Dayley/dp/0470375000/ref=sr_1_2?ie=UTF8&s=books&qid=1224844673&sr=1-2

Has anyone bought this, if so is it worth it? Also, what about the MS book "Introducing Silverlight 2"?:

http://www.amazon.co.uk/Introducing-Microsoft-Silverlight-Second-PRO-Developer/dp/073562528X/ref=pd_bxgy_b_text_b

Cheers
Kev

From stackoverflow
  • I'm rather waiting for Programming Silverlight 2 by Jesse Liberty and Tim Heuer.

    Update: See Jesse Liberty's post here, at the bottom he recommends some Silverlight 2 books.

    Kev : Yes that's the one I'm looking forward to reading too.
  • I am currently reading Microsoft's "Introducing Silverlight 2" and I really like it. It's a great book if you are just starting with Silverlight. Though he has a tendancy to repeat examples which can be annoying.

  • I think that there are 2 distinct audiences when it comes to Silverlight books and other technical resources.

    Those totally new to XAML and Silverlight will benefit from introductory books and a clean briefing in the technology, whereas those who are coming to it from the world of WPF and existing knowledge of XAML seem better served, at the moment at least, by the excellent blogs out there - like Jesse's & Tim's and Silverlight insiders like Jeff Wilcox, Ning Zhang, Beatriz Sollnitz etc.

    I will almost certainly buy Programming Silverlight 2 when it is available, but I have not gone for any of the currently published books which I think fall into the introductory category.

  • I have a copy of Pro Silverlight 2 in C# 2008 and I'm happy with it. It skips the introductory (i.e. what is html) and starts with more technical matters. A coworker had good things to say about the author. Has a good preview available on Google Books.

    A brief look at the subjects in Silverlight 2 Bible tells me that there's a lot of space wasted on tasks that many devs have already done (installing VS 2008 for instance). And no preview available on Google Books.

    Kev : Thanks - I'll look that one out. I quite the APress texts, no mucking about teaching you to suck eggs for the first half of the book like Wrox.

Store a number in an integer string and recall it in a later action

I'm currently trying to get a UISlider to work.

I'm trying to set the strings value as 8 to start off with on view load.

Then when the slider changes value I want the string to update with that number, and then later on I can use the value in the string for a setDuration:## later on in another action.

Any ideas?

From stackoverflow
  • To update the string you just get the value and do:

    NSString *myString = [NSString stringWithFormat:@"%f", [slider value]];
    

    To get the string value back as a float you just do:

    float myValue = [myString floatValue];
    
  • I ended up using CAFloat..

What is the best unit testing tool for a mix of managed and unmanaged C++?

I am going to start implementing some unit tests for a codebase that is a mix of managed and unmanaged C++. Can NUnit hack it with unmanaged code? Is there a better alternative?

From stackoverflow
  • It's possible to use NUnit to test unmanaged code, example:

    // Tests.h
    
    #pragma once
    
    #include <cmath>
    
    using namespace System;
    using namespace NUnit::Framework;
    
    namespace Tests {
    
        [TestFixture]
        public ref class UnitTest
        {
        public:
         UnitTest(void) {}
    
         [Test]
         void TestCos()
         {
          Assert::AreEqual(1, cos(0.0));
         }
    
        };
    }
    
  • NUnit will work fine with unmanaged code as long as you write the unit tests in managed C++. The outside wrapper will be NUnit friendly and can access the unmanaged parts.

Which is the better framework to build a HTML survey builder?

I’ve to build a HTML survey builder application with an AJAXified user interface (i.e.Wufoo,...).

The typical survey will be multistep with multi-dependencies between form fields/questions, public access most of the time, and export results to PDF + CSV.

Have been studying/testing some PHP frameworks ( CodeIgniter, Symfony and CakePHP). I like CakePHP, but I read a lot of good stuff about Django and RoR (especially RoR for form building...)...

...so the question: which is the better framework to build a HTML survey builder?

From stackoverflow
  • I'd say all the frameworks you mention are a good fit for such an application. So the question mainly becomes: Which is your set of expertise? If you are very proficient in PHP and haven't ever seen Ruby or Python, then one of the PHP ones is certainly a better fit if you wish rapid development.

    I'd stick with the framework I like written in the language I know best.

    Also, in my experience it's best to avoid RoR's scaffolding (automatic form creation) when you'll be doing variable length autogenerated forms. You can take a look on Railscasts for more info about that and how to go about it.

  • My personal opinion is that Zend Framework is the best in cases like this one. It's very modular and it also provides nice export components.

    You would probably be interested in Zend Ajax and Zend_Pdf components. You can also use most of them as standalone classes.

    You can find a list and documentation with examples of all Zend Frameworks components here.

How to call a client side javascript function after a specific UpdatePanel has been loaded

How is is possible to call client side javascript method after a specific update panel has been loaded?

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler) does not work for me because this will fire after ANY update panel finishes loading, and I can find no client side way to find which is the one

ScriptManager.GetCurrent(Page).AsyncPostBackSourceElementID AsyncPostBackSourceElementID does not work for me as this is a server side object, and i want Client Side

The ClientSide .Net framework must know which UpdatePanel it is updating in order to update the correct content. Surely there is a way to hook into this event?

Any help appreciated

From stackoverflow
  • This may be your solution.

    In the code behind for the UpdatePanel's OnLoad event, register a startup script.

    string scriptText = "alert('Bar!');";
        ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "foo", scriptText, true);
    

  • You can hook the PageRequestManager.beginRequest event and inspect the BeginRequestEventArgs.postBackElement property.

    Note that it doesn't really give you the UpdatePanel, but the control inside of the UpdatePanel. That should be good enough, though.

    Edit: Even better, the PageRequestManager.pageLoaded event gives you PageLoadedEventArgs.panelsUpdated (and panelsCreated) properties.

  • Thanks - both good answers. I went with the client side script "pageloaded" in the end. That is a fairly buried method that google did not reveal to me. For those who are interested, this code works with FireBug to give a good demo of the PageLoaded method working to find the updated panels:

    <script type="text/javascript">
         $(document).ready(function() {
          panelsLoaded = 1;
          Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(PageLoaded)
         });
    
         function PageLoaded(sender, args) {
          console.log("I have occured " + panelsLoaded++ + " times!");
    
          var panelsCreated = args.get_panelsCreated();
          for (var i = 0; i < panelsCreated.length; i++) {
           console.log("Panels Updating: " + panelsCreated[i].id);
          }
    
          var panelsUpdated = args.get_panelsUpdated();
          for (var i = 0; i < panelsUpdated.length; i++) {
           console.log("Panels Updating: " + panelsUpdated[i].id);
          }
         }
        </script>
    
    Mark Struzinski : Thanks for leaving the code. This helped me a lot!!!
    Steve Wortham : Yes, big help for me as well almost a year later. Thank you.
    Deniz Dogan : +1 for leaving the code, helped me as well.
    Peter Bernier : This was extremely helpful. Thank you!
  • I have a similar issue. None of the events of the PageRequestManager are firing for me. I attempted to wire up to the initialize, begin and end request methods but they do not seem to fire.

    link href="Stylesheet1.css" rel="stylesheet" type="text/css" />

    <title>Mirant</title>
    
    <script language="javascript" type="text/javascript">
    
        var oldgridSelectedColor;
    
        var prm = Sys.WebForms.PageRequestManager.getInstance();
    
        prm.add_pageLoaded(pageLoaded);
    
        prm.add_beginRequest(beginRequest);
    
        prm.add_initializeRequest(Init):
    
        Sys.WebForms.PageRequestManager.getInstance().add_endRequest(setscrollPos);
    
        var postbackElement;
    
    
    
        // This Script is used to maintain Grid Scroll on Partial Postback
    
    
    
        function setMouseOverColor(element) {
    
            oldgridSelectedColor = element.style.backgroundColor;
    
            //element.style.backgroundColor = '#FF6699';
    
            element.style.cursor='hand';
    
            element.style.textDecoration='none';
    
        }
    
    
    
        function setMouseOutColor(element)
    
        {
    
            element.style.backgroundColor=oldgridSelectedColor;
    
            element.style.textDecoration='none';
    
        }
    
        function Init(sender, args) {
    
            alert('init');
    
        }
    
    
    
        function setscrollPos(sender, args) {
    
            alert('got it');
    
            $get("divScroll").scrollTop = $get("hdnScrollTop").value;
    
        }
    
        function beginRequest(sender, args) {
    
            postbackElement = args.get_postBackElement();
    
        }
    
    
    
        function pageLoaded(sender, args) {
    
            alert('got it');
    
            var updatedPanels = args.get_panelsUpdated();
    
            if (typeof (postbackElement) == "undefined") {
    
                alert('ERROR');
    
                return;
    
            }
    
            if (postbackElement.id.toLowerCase().indexOf('gridviewapprovals') > -1) {
    
    
    
                $get("divScroll").scrollTop = $get("hdnScrollTop").value;
    
            }
    
        }
    
        function scroll(pos) {
    
    
    
            $get('hdnScrollTop').value = pos;
    
            alert($get('hdnScrollTop').value)
    
        }
    
    </script>
    
    <style type="text/css">
    
         .WrapperDiv {
    
                width:800px;height:400px;border: 1px solid black;
    
            }        
    
            .WrapperDiv TH {
    
                position:relative;
    
            }
    
            .WrapperDiv TR 
    
            {
    
                /* Needed for IE */
    
                height:0px;
    
            } 
    
    
    
        .HeaderText
    
        {
    
            font-family: tahoma;
    
            font-size: medium;
    
            font-weight: bold;
    
            color: #0000FF;
    
        }
    
        .NormalText
    
        {
    
            font-family: tahoma;
    
            font-size: small;
    
            color: #0000FF;
    
        }
    
        .DetailText
    
        {
    
            font-family: tahoma;
    
            font-size: large;
    
            font-weight: bold;
    
            color: #0000FF;
    
        }
    
        .modalBackground {
    
            background-color:Gray;
    
             filter:alpha(opacity=70);
    
            opacity:0.7;
    
        }
    
    
    
        .ModalPopup
    
        {
    
            font-family: tahoma;
    
            background-color: #CCFFFF;
    
            border: thick groove #0000FF;
    
            padding: 4px;
    
            margin: 5px 10px 5px 10px;
    
        }
    

    .HeaderFreez

    {

    position:relative ;

    top:expression(this.offsetParent.scrollTop);

    z-index: 10;

    background-color:  Navy;
    
    border-bottom: groove 4 Blue;
    
    z-index:0;
    
    color: White
    

    }

        </style>
    

    <form id="form1" runat="server" title="Assigned Approvals">
    
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="True"  />
    
    
    
    <asp:UpdatePanel ID="updatePanel1" runat="server" UpdateMode="Conditional">
    
    <ContentTemplate>
    
    
    
    <cc1:AlwaysVisibleControlExtender ID="AlwaysVisibleControlExtender2" 
    
        runat="server"
    
         TargetControlID="instructionsPanel" 
    
         VerticalSide="Top" VerticalOffset="0" 
    
         HorizontalSide="Right" HorizontalOffset="0" 
    
          ScrollEffectDuration=".1" >
    
    </cc1:AlwaysVisibleControlExtender>  
    
    <asp:Panel runat="server" ID="instructionsPanel" Width="100%" BackColor="White" 
    
            BorderColor="#3333CC" BorderStyle="Groove" BorderWidth="2px">
    
                        <span class="HeaderText">Instructions </span>
    
                        <br />
    
                        <span class="NormalText" >1. Select either Approve, Remove, or Change Access for 
    
                        each row.
    
                        <br />
    
                        2. If you selected Change, you must provide a description of the modification.
    
                        <br />
    
                        3. Click the Complete button at the bottom of the screen after you&#39;ve reviewed 
    
                        ALL of your approvals.
    
                        <br />
    
                        <span class="HeaderText"  />
    
                        <br />
    
                        NOTE: THIS DOES NOT REMOVE THE USER. THIS APPLICATION JUST SENDS NOTIFICATION TO 
    
                        THE APPLICATION OWNERS TO PERFORM YOUR SUGGESTED ACTIONS. 
    
                    </asp:Panel>
    
    <div align="center" style="padding: 4px; margin: 4px; width:auto; height:600px; overflow: visible;" runat="server">
    
           <table width="100%" style="margin-top: 145px;" runat="server">
    
            <tr>
    
                <td colspan="2">
    
                    <asp:Panel runat="server" ID="spaceSaver" BackColor="Green"
    
                     BorderStyle="Groove" BorderWidth="4" BorderColor="Blue" >
    
                    </asp:Panel>
    
                </td>
    
            </tr>
    
            <tr style="position: absolute; top: 10px">
    
                <td style="border: medium groove #0000FF; width: 50%; position: absolute;" class="NormalText" 
    
                    bgcolor="#CCFFFF" >
    
                    <input type="hidden" id="hdnScrollTop" runat="server" value="0" /> 
    
                    <div id="divScroll"  style="width:500px;height:400px; overflow:scroll;"  onscroll="$get('hdnScrollTop').value = this.scrollTop;" runat="server" >
    
    
    
                        <asp:GridView ID="GridViewApprovals" runat="server" AutoGenerateColumns="False" 
    
                            DataSourceID="soaDataSource" DataKeyNames="Id" 
    
                            onrowdatabound="GridViewApprovals_RowDataBound" 
    
                            onselectedindexchanged="GridViewApprovals_SelectedIndexChanged" 
    
                            Width="100%"  AllowPaging="False">
    
                            <HeaderStyle CssClass="HeaderFreez" />
    
    
    
                            <Columns>
    
                                <asp:BoundField DataField="Id" HeaderText="Id" SortExpression="Id" />
    
                                <asp:BoundField DataField="AuditableApplicationName" HeaderText="Application" 
    
                                    SortExpression="AuditableApplicationName" />
    
                                <asp:BoundField DataField="UserFullName" HeaderText="User" 
    
                                    SortExpression="UserFullName" />
    
                                <asp:TemplateField HeaderText="Continue" SortExpression="ContinueAccess">
    
                                    <ItemTemplate>
    
                                        <asp:CheckBox ID="cbContinueAccess" runat="server" 
    
                                            Checked='<%# Bind("ContinueAccess") %>' 
    
                                            oncheckedchanged="cbContinueAccess_CheckedChanged" />
    
                                    </ItemTemplate>
    
                                </asp:TemplateField>
    
                                <asp:TemplateField HeaderText="Remove" SortExpression="RemoveAccess">
    
                                    <ItemTemplate>
    
                                        <asp:CheckBox ID="cbRemoveAccess" runat="server" 
    
                                            Checked='<%# Bind("RemoveAccess") %>' 
    
                                            oncheckedchanged="cbRemoveAccess_CheckedChanged" />
    
                                    </ItemTemplate>
    
                                </asp:TemplateField>
    
                                <asp:TemplateField HeaderText="Change" SortExpression="ChangeAccess">
    
                                    <ItemTemplate>
    
                                        <asp:CheckBox ID="cbChangeAccess" runat="server" 
    
                                            oncheckedchanged="cbChangeAccess_CheckedChanged" CausesValidation="true" 
    
                                            />
    
                                    </ItemTemplate>
    
                                </asp:TemplateField>
    
                            </Columns>
    
                            <SelectedRowStyle BackColor="#6699FF" />
    
                        </asp:GridView>
    
                        <asp:ObjectDataSource ID="soaDataSource" runat="server" 
    
                            SelectMethod="GetApprovals" 
    
                            TypeName="SOABuddy.Silverlight.Web.ApprovalItemsProvider">
    
                        </asp:ObjectDataSource>
    
                    </div>
    
                </td>
    
                <td  style="border: medium groove #000080; width: 50%;" class="NormalText" valign="top";   >
    
                    <cc1:AlwaysVisibleControlExtender ID="AlwaysVisibleControlExtender1" 
    
                            runat="server"
    
                             TargetControlID="authDetails" 
    
                             VerticalSide="Top" VerticalOffset="150" 
    
                             HorizontalSide="Right" HorizontalOffset="10"
    
                              ScrollEffectDuration=".1">
    
                        </cc1:AlwaysVisibleControlExtender>    
    
    
    
                    <asp:Panel runat="server" ID="authDetails" style=" padding: 10px ; border: thick groove #0000FF; 
    
                         width: 400px; height: 380px; background-color: #CCFFFF; " 
    
                        BackColor="#CCFFFF" >
    
                          <table class="NormalText" id="tableDetails">
    
                            <tr>
    
                                <td style="overflow: auto; width: 15%;">
    
                                    User Name:
    
                                </td>
    
                                <td class="DetailText" style="border: medium groove #0000FF; width: 30%;" >
    
                                    <asp:Literal  ID="userName" runat="server"></asp:Literal>
    
                                </td>
    
    
    
                            </tr>
    
                            <tr>
    
                                <td>
    
                                    User ID:</td>
    
                                <td class="DetailText">
    
                                    <asp:Literal ID="userId" runat="server"></asp:Literal>
    
                                </td>
    
                            </tr>
    
                            <tr>
    
                                <td>
    
                                    Application User ID:</td>
    
                                <td class="DetailText">
    
                                    <asp:Literal ID="applicationUserId" runat="server"></asp:Literal>
    
                                </td>
    
                            </tr>
    
                            <tr>
    
                                <td>
    
                                    Application Resource:</td>
    
                                <td class="DetailText">
    
                                    <asp:Literal ID="applicationResource" runat="server"></asp:Literal>
    
                                </td>
    
                            </tr>
    
                            <tr>
    
                                <td>
    
                                    Last Login:</td>
    
                                <td class="DetailText">
    
                                    <asp:Literal ID="lastLogin" runat="server"></asp:Literal>
    
                                </td>
    
                            </tr>
    
                            <tr>
    
                                <td>
    
                                    Roles</td>
    
                                <td class="NormalText">
    
                                    <asp:ListBox ID="listBoxRoles" runat="server" Width="95%"></asp:ListBox>
    
                                </td>
    
                            </tr>
    
                            <tr >
    
                                <td>
    
                                    &nbsp;</td>
    
                                <td class="NormalText">
    
                                    &nbsp;</td>
    
                            </tr>
    
                            <tr style="height: 100px;">
    
                                <td>
    
                                    Change Comments</td>
    
                                <td class="NormalText">
    
                                    <asp:TextBox ID="tbChangeComments" runat="server" Height="100" 
    
                                        TextMode="MultiLine" Width="95%" BorderColor="White"></asp:TextBox>
    
                                </td>
    
                            </tr>
    
                        </table>
    
                    </asp:Panel>
    
                </td>
    
            </tr>
    
            <tr>
    
                <td class="NormalText">    
    
                    footer
    
                    <asp:LinkButton ID="dummy" runat="server" ></asp:LinkButton>
    
                    <cc1:ModalPopupExtender ID="Comments_ModalPopupExtender" runat="server" 
    
                            TargetControlID="dummy" 
    
                            CancelControlID="ButtonCommentsCancel"
    
                            OkControlID="ButtonCommentsOK" 
    
                            BackgroundCssClass="modalBackground"
    
                            PopupControlID="PanelComments" 
    
                            OnOkScript="saveComment"
    
                            DropShadow="true">
    
    
    
                        </cc1:ModalPopupExtender>
    
                    <asp:Panel ID="PanelComments" runat="server" CssClass="ModalPopup"
    
                        BorderColor="#0033CC" BorderStyle="Groove" BorderWidth="4px"
    
                         Width="400"  Height="150">
    
                        <span class="HeaderText" />
    
                        Enter comments for the change request:<br />
    
                        <br />
    
    
    
                        <asp:TextBox ID="tbComments" runat="server" Height="54px" TextMode="MultiLine" 
    
                           class="NormalText" Width="97%"></asp:TextBox>
    
                        <br />
    
                        <br />
    
                        <asp:Button ID="ButtonCommentsOK" runat="server" Text="OK" 
    
                            onclick="ButtonCommentsOK_Click" Width="100px" UseSubmitBehavior="False" />
    
                        &nbsp;&nbsp;&nbsp;
    
                        <asp:Button ID="ButtonCommentsCancel" runat="server" Text="Cancel" 
    
                            Width="100px" />
    
                    </asp:Panel>
    
                </td>
    
            </tr>
    
        </table>
    
    </div>
    
    </ContentTemplate>
    
    </asp:UpdatePanel>
    
    
    
    <%--<asp:Panel ID="PanelChangeComments" runat="server" CssClass="HeaderText" 
    
        Height="213px" Width="530px" Visible="False">
    
        Enter change comments:<br />
    
        <br />
    
        <asp:TextBox ID="tbEnterChangeComments" runat="server" Height="119px" 
    
            TextMode="MultiLine" Width="525px"></asp:TextBox>
    
        <br />
    
        <br />
    
        <span class="NormalText"></span>
    
           <asp:Button ID="btnChangeCommentsOK" runat="server" Text="OK" 
    
            onclick="btnChangeCommentsOK_Click" />
    
           <asp:Button ID="btnChangeCommentsCancel" runat="server" Text="Cancel" />
    
    </asp:Panel>--%>
    
    
    
    </form>
    

    any ideas?

  • @lisa:

    Try creating delegates for you functions first, and then add them to the event queue:

    var pageLoaded = Function.createDelegate(this, pageLoaded);
    prm.add_pageLoaded(pageLoaded);
    

How to work with referenced projects in eclipse

Ok maybe everybody knows how to do this, but I've never try it beacause I've never needed it so, how do you work with multiple referenced projects in eclipse? I have a couple of Struts 1 web applications that must use another struts 1 "library" project and right now I'm doing the communication between them using url requests, wich is really annoying (at least how I have implemented it).

I would like to be able to use the classes of the "library" project directly in my other struts applications.

So far I know there are supposed to be in the same workspace and that I must reference using the "project references" options in the project properties, but that's it! I really don't know what to do next.

Thanks!

From stackoverflow
  • Projects Menu -> properties

    Go to the Java Build Path.

    There, you can either add the library directly or add another project into the build path of the current project.

  • Ok, that did it! Now when I export the struts application in a WAR file what is going to happen to the struts library application? Do I need to export both in separate WAR files or just by exporting the primary applicacion WAR will export also all the files of the library web application?

  • You probably just need the necessary jar files and either include them with your WAR, or add them to your Application Server (many have different ways of doing this).

    Another option is to bundle each WAR in one EAR file. This approach won't work on Tomcat, but will work on WebSphere, WebLogic ...

Is it possible to convert an OCX file to a TLB file for Borland C++?

I'm trying to automate a build, but the instructions require openning an OCX in Borland C++ Builder and saving it as a TLB. How can I reproduce this process through the command line?

From stackoverflow
  • Did you look at the help for the IDE command line or the other tools/executables?

  • If I recall, you can use tlbimport. I will admit it's been a long time, and tlbimport may have been part of the VC++ redist.

  • It's not the nicest solution, but it's the only one I can find that works automatically. I downloaded a free program called AutoHotkey to emulate the keystrokes for openning the ocx file in BCB5, checking off the 'Can Create' checkbox under the Flags tab and saving the file as a tlb. It helps get through the annoying translation warning as well!

  • With Delphi/C++Builder 2009, you can use the TLIBIMP and GENTLB command line tools:

    1. 1. tlibimp -I comdlg32.ocx -Ftcomdlg32
      This will generate a comdlg32.ridl file (RIDL is a variant of Microsoft's IDL).
    2. 2. gentlb comdlg32.ridl
      This generates the comdlg32.tlb file.

Weekly period in Access 2007

Is there a way to define the weekly period I would like to use on a report, Currently Access has the week defined as sun through sat, I would like to use mon through sun.

From stackoverflow
  • The Weekday function has an optional parameter to define the start day - is that any use?

What's the best strategy for get/setting metadata on Ruby methods at runtime?

I have a class with some methods. It's supersekret but I've reproduced what I can here.

Class RayGun
  # flashes red light
  # requires confirmation
  # makes "zowowowowowow" sound
  def stun!
    # ...
  end

  # flashes blue light
  # does not require confirmation
  # makes "trrrtrtrtrrtrtrtrtrtrtr" sound
  def freeze!
    # ...
  end

  # doesn't flash any lights
  # does not require confirmation
  # makes Windows startup sound
  def killoblast!
    # ...
  end
end

I want to be able to, at runtime, interrogate the class about one of the methods and receive a hash or struct like so:

  {:lights => 'red', :confirmation => false, :sound => 'windows'}

What's the best way of doing this? Obviously you could have separate YAML file alongside and set up a convention to relate the two, but ideally I want code and metadata in one place.

The most promising idea I can come up with is something like this:

class RayGun
  cattr_accessor :metadata
  def self.register_method(hsh)
    define_method(hsh.name, hsh.block)
    metadata[hsh[:name]] = hsh
  end

  register_method({
    :name => 'stun!', 
    :lights => 'red', 
    :confirmation => 'true', 
    :sound => 'zowowo',
    :block => Proc.new do
      # code goes here
   })

   # etc.
end

Anyone got some better ideas? Am I barking up a very wrong tree?

From stackoverflow
  • Just a little beautyfication:

    class RayGun
      cattr_accessor :metadata
      def self.register_method(name, hsh, &block)
        define_method(name, block)
        metadata[name] = hsh
      end
    
      register_method( 'stun!',
        :lights => 'red', 
        :confirmation => 'true', 
        :sound => 'zowowo',
        ) do
          # code goes here
      end
    
       # etc.
    end
    

    You do lose easy access to the original closure, but probably don't need it.

    To answer the question, it doesn't look bad, you could do something a little more convetional but probably good enough:

    class RayGun
      cattr_accessor :metadata
    
      @metadata[:stun!] = {:lights => 'red', 
                            :confirmation => 'true', 
                            :sound => 'zowowo'}
      def stun!
        # ...
      end
    
       # etc.
    end
    

    In the original example register_method is public, if you planned to use it that way then the second option becomes less usefull because it doesn't ensure consistency.

  • There's the YARD tool which lets you add metadata to methods. I'm pretty sure it just sticks the metadata into the rdoc files you generate, but you could easily build off of that to get runtime information.

  • I found another strategy poking around http://github.com/wycats/thor/tree. Thor lets you write stuff like this:

    Class RayGun < Thor
      desc "Flashes red light and makes zowowowowow sound"
      method_options :confirmation => :required
      def stun!
        # ...
      end
    end
    

    It manages this by using the (undocumented) hook Module#method_added. It works like this:

    1. Call to Thor#desc and Thor#method_options set instance variables @desc, @method_options.

    2. Defining method stun! calls Thor#method_added(meth)

    3. Thor#method_added registers Task.new(meth.to_s, @desc, @method_options) (roughly speaking) and unsets @desc, @method_options.

    4. It's now ready for the next method

    Neat! So neat that I am going to accept my own answer :)

    Daniel Ribeiro : method_added may be undocumented on rdoc, but it is on a documentation linked by the official site: http://www.ruby-doc.org/docs/ProgrammingRuby/html/ospace.html