A "with block" is a form of SyntacticSugar -- a way of saying "I'm going to do a couple (or a bunch) of things with this one instance of this structure/record/class, so please assume that the following method/property/field accesses are relative to this object." See also WithBlockCodeSmell -- largely an argument that you shouldn't use WITH blocks. ---- '''[VisualBasic]''' In VisualBasic and most variations, one can simplify the syntax of multiple method/property calls to the same object, like this: With Active''''''Document: .Save''''''As "backup.doc" Set Header''''''Table = .Tables(1) Set Address''''''Table = .Tables(2) Set Invoice''''''Table = .Tables(3) End With Header''''''Table.Select ' selects Active''''''Document.Tables(1) Unfortunately, VbScript doesn't have With blocks, making this kind of code much uglier, and perhaps even slower (see the bit on dereferencing in Pascal below). ---- '''[PascalLanguage]''' PascalLanguage has had "with" statements since the very beginning, and they're still present in current implementations, such as Borland's DelphiLanguage. On the plus side, they can make the code much more readable. On the minus side, they can lead to bugs that cause you to tear your hair out, because you can't see what's right in front of you, namely that the variable named Foo is actually Some''''''Object.Foo and not the outer-level Foo that you think it is. I've pretty much given up on using "with" in my own code, although there are times when I look wistfully at a tedious-looking block of code and consider relenting. ''(aside: Visual Basic gets around this problem by assuming that all variables are specified as usual, only assuming an object member if the name is preceded by a dot.)'' There used to be another advantage for using "with": If you had some (Delphi) code that looked like this... My''''''Object.Foo := 42; My''''''Object.Bar := 'forty-two'; My''''''Object.Baz := My''''''Other''''''Object.Baz; then the compiler would have to dereference the My''''''Object pointer for each and every statement. Using "with" meant doing the dereferencing only once: with My''''''Object do begin Foo := 42; Bar := 'forty-two'; Baz := My''''''Other''''''Object.Baz end; But nowadays, the Delphi optimizer is smart enough to factor out the pointer dereferencing, even if you write code that looks like the first example. -SteveSchafer Err... how can a "with" block remove the dereference of the My''''''Object pointer? I can see how the code below could reduce pointer dereferences by caching the value of O1.O2.O3 and avoiding multiple dereferences through O1 and O2, but in the code above I cannot imagine how use of the My''''''Object pointer could be avoided. with O1.O2.O3 do begin Foo := 42; Var := 'forty-two' end The "with" block doesn't eliminate ''all'' dereferencing of the My''''''Object pointer, only the ''redundant'' dereferencing. Let's look at what goes on when accessing My''''''Object.Foo (we'll assume that Foo is a simple field of the object). My''''''Object is a variable that holds a pointer to the actual object instance, allocated on the heap. Given My''''''Object.Foo := 42; this is the code generated by the Delphi 5.0 compiler: mov eax,[My''''''Object] // get the value of the pointer to // My''''''Object into the EAX register mov [eax+32],42 // offset that value by 32 to get to the Foo field, // then store the value 42 into that location Now, in the naive (Delphi 1.0) implementation, repeated references to My''''''Object. would cause the EAX register to be reloaded from the My''''''Object variable each time, whereas a "with" block would cause it to be loaded only once. Since Delphi 2.0, the compiler's optimizer has been able to figure out that it doesn't need to do the repeated register reloads, even without the "with" block. -ss ----- '''[CobolLanguage]''' COBOL has "MOVE CORRESPONDING source-structure TO destination-structure" which copies the values of all fields with the same names, recursively. This is not the same as a PascalLanguage/VisualBasic "with" statement, but in some ways it's a related concept. ---- '''[SmalltalkLanguage]''' SmalltalkLanguage has semicolons for this purpose: Transcript show: 'a'; show: 'b'. ---- '''[CeeLanguage, CeePlusPlus and other block structured (AlgolFamily) languages]''' In C++, and most other languages, you can create an extra locally-scoped variable to hold the common subexpression: { Document *d = a''''''ctiveDocument; d->S''''''aveAs( "backup.doc" ); d->S''''''etHeaderTable( tables[1] ); d->S''''''etAddressTable( tables[2] ); d->S''''''etInvoiceTable( tables[3] ); } // d goes out of scope here. It just comes out with the wash if you write short functions. This would become a function with a signature like: void S''''''etTables( Document *d, const Table tables[3] ); and called with activeDocument as argument. or activeDocument->Set''''''Tables(tables); //at which point you should see why with smells. ''[see WithBlockCodeSmell]'' ---- [PythonLanguage] As in C++, you can create an extra variable to hold the common subexpression. Yet, unlike C++, there are no curly braces in Python to limit its scope and name visibility. # reference to object annoyinglyLongNameForActiveDocument = Document() # new reference to existing object d = annoyinglyLongNameForActiveDocument d.saveAs('backup.doc') d.setHeaderTable(table[1]) d.setAddressTable(table[2]) d.setInvoiceTable(table[3]) # delete d from namespace now (GarbageCollection happens later) del d # object and long reference still exist annoyinglyLongNameForActiveDocument.saveAs('backup.doc') Although it's perfectly doable, using this construct could indicate poor design in your program (WithBlockCodeSmell). ----- '''[RubyLanguage]''' I know of instance_eval in RubyLanguage, but I suspect it's not a true analogue of the above. ''True, but you can easily write this'': def with(obj,&block) obj.instance_eval &block end with 'foo' do puts size #=> 3 puts self #=> foo end ''Nice showing of blocks' power, ain't it?'' ----- '''[JavaScript]''' In JavaScript you can use "with". The runtime will search the provided object for fields and methods before searching the normal search path: with ( activeDocument ) { saveAs("document.doc"); setHeaderTable( tables[0] ); setAddressTable( tables[1] ); } ---- '''[CommonLisp]''' (with-slots (a b) obj (setf a 1 b 2)) You can avoid any aliasing problems by renaming the slots. eg. (let ((a 42)) (with-slots ((aa a) b) obj (setf aa 99 b 2)) (values a (slot-value obj 'a))) => 42, 99 with-accessors is also available. with-accessors works the same way but deals with the object's accessors (generic functions) rather than directly with the instance variables. ---- '''[IoLanguage]''' Object (the top-level prototype) provides the do message, which evaluates all its contents in that object's scope. Often used to produce the analogue of a class definition: NewObj := Object clone do ( method_one := method(do_stuff) method_two := method(do_other_stuff) ) ---- Is there anything similar in other languages? ''PerlLanguage's DollarUnderscore construct? or is that another can of worms?'' ''Yes, Perl is a can of worms.'' Perl is a ''cannery'' of worms. ''Perl can worm its way out of anything.''