text:
Complex Analysis/Complex Functions/Complex Derivatives

Complex differentiability
Let us now define what complex differentiability is.

The function
 * Example 2.3.2
 * $$f:\Complex\to\Complex,f(z)=\bar z$$

is nowhere complex differentiable.

Let $$z_0\in\Complex$$ be arbitrary. Assume that $$f$$ is complex differentiable at $$z_0$$, i.e. that
 * Proof
 * $$\lim_{z\to z_0\atop z\in\Complex}\frac{\bar z-\bar{z}_0}{z-z_0}$$

exists.

We choose
 * $$\begin{align}A:=\{z\in\Complex|\Re z=\Re z_0\}\\B:=\{z\in\Complex|\Im z=\Im z_0\}\end{align}$$

Due to lemma 2.2.3, which is applicable since of course $$\Complex$$ is open, we have:
 * $$\lim_{z\to z_0\atop z\in A}\frac{\bar z-\bar{z}_0}{z-z_0}=\lim_{z\to z_0\atop z\in\Complex}\frac{\bar z-\bar{z}_0}{z-z_0}=\lim_{z\to z_0\atop z\in B}\frac{\bar z-\bar{z}_0}{z-z_0}$$

But
 * $$\begin{align}&\lim_{z\to z_0\atop z\in A}\frac{\bar z-\bar{z}_0}{z-z_0}=\lim_{z\to z_0\atop z\in A}\frac{\Re(z-z_0)-i\Im(z-z_0)}{\Re(z-z_0)+i\Im(z-z_0)}=-1\\\\

&\lim_{z\to z_0\atop z\in B}\frac{\bar z-\bar{z}_0}{z-z_0}=\lim_{z\to z_0\atop z\in B}\frac{\Re(z-z_0)-i\Im(z-z_0)}{\Re(z-z_0)+i\Im(z-z_0)}=1\end{align}$$ a contradiction.

The Cauchy–Riemann equations
We can define a natural bijective function from $$\Complex$$ to $$\R^2$$ as follows:
 * $$\Phi(x+yi):=(x,y)$$

In fact, $$\Phi$$ is a vector space isomorphism between $$\Complex^1$$ and $$\R^2$$.

The inverse of $$\Phi$$ is given by
 * $$\Phi^{-1}:\R^2\to\Complex,\Phi^{-1}(x,y)=x+yi$$

1. We prove well-definedness of $$u,v$$.
 * Proof

Let $$(x,y)\in\Phi(O)$$. We apply the inverse function on both sides to obtain:
 * $$x+yi\in\Phi^{-1}(\Phi(O))=O$$

where the last equality holds since $$\Phi$$ is bijective (for any bijective $$f:S_1\to S_2$$ we have $$f^{-1}\bigl(f(S_3)\bigr)=f\bigl(f^{-1}(S_3)\bigr)=S_3$$ if $$S_3\sube S_1$$ ; see exercise 1).

3. We prove differentiability of $$u$$ and $$v$$ and the Cauchy-Riemann equations.

We define
 * $$\begin{align}S_1:=\{z\in\Complex:\Re(z)=\Re(z_0)\}\cap O\\S_2:=\{z\in\Complex:\Im(z)=\Im(z_0)\}\cap O\end{align}$$

Then we have:
 * $$\begin{align}

\partial_xu(x_0,y_0)&=\lim_{x\to x_0}\frac{u(x,y_0)-u(x_0,y_0)}{x-x_0}&\\ &=\lim_{x\to x_0}\frac{\Re\bigl(f(x+y_0i)\bigr)-\Re\bigl(f(x_0+y_0i)\bigr)}{x-x_0}&\\ &=\Re\left(\lim_{x\to x_0}\frac{f(x+y_0i)-f(x_0+y_0i)}{x-x_0}\right)&\text{continuity of }\Re\\ &=\Re\left(\lim_{z\to z_0\atop z\in S_2}\frac{f(z)-f(z_0)}{z-z_0}\right)&\\ &=\Re\left(\lim_{z\to z_0\atop z\in S_1}\frac{f(z)-f(z_0)}{z-z_0}\right)&\text{lemma 2.2.3}\\ &=\Re\left(\lim_{y\to y_0}\frac{f(x_0+yi)-f(x_0+y_0i)}{yi-y_0i}\right)&\\ &=\Re\left((-i)\lim_{y\to y_0}\frac{f(x_0+yi)-f(x_0+y_0i)}{y-y_0}\right)&i^{-1}=-i\\ &=\Im\left(\lim_{y\to y_0}\frac{f(x_0+yi)-f(x_0+y_0i)}{y-y_0}\right)&\\ &=\partial_yv(x_0, y_0) \end{align}$$ From these equations follows the existence of $$\partial_xu(x_0,y_0),\partial_yv(x_0,y_0)$$, since for example
 * $$\lim_{z\to z_0\atop z\in S_2}\frac{f(z)-f(z_0)}{z-z_0}$$

exists due to lemma 2.2.3.

The proof for
 * $$\partial_yu(x_0,y_0)=-\partial_xv(x_0,y_0)$$

and the existence of $$\partial_yu(x_0,y_0),\partial_xv(x_0,y_0)$$ we leave for exercise 2.

Exercises

 * 1) Let $$S_1,S_2,S_3$$ be sets such that $$S_3\sube S_1$$, and let $$f:S_1\to S_2$$ be a bijective function. Prove that $$f^{-1}\bigl(f(S_3)\bigr)=f\bigl(f^{-1}(S_3)\bigr)=S_3$$.
 * 2) Let $$O\sube\Complex$$ be open, let $$f:O\to\Complex$$ be a function and let $$z_0=x_0+y_0i\in O$$ . Prove that if $$f$$ is complex differentiable at $$z_0$$, then $$\partial_yu(x_0,y_0)$$ and $$\partial_xv(x_0,y_0)$$ exist and satisfy the equation $$\partial_yu(x_0,y_0)=- \partial_xv(x_0,y_0)$$.

Next


text:
Cookbook:Yerushalmi Kugel (Sweet Noodle Casserole)

| Cuisine of Israel

Yerushalmi kugel is named after the city of Jerusalem. Legend has it that it originated in Jerusalem with the followers of the Vilna Gaon in the 18th century.

Ingredients

 * 8 oz (200 g) noodles (egg noodles are preferred, but others work fine as well)
 * ⅔ cup (160 g) sugar (white sugar is helpful because it's more obvious when it begins to brown)
 * 4 tbsp olive oil
 * 1 handful of raisins
 * 1–2 tsp pepper
 * 1 tsp cinnamon
 * 3 eggs

Procedure

 * 1) Boil noodles according to the package instructions and drain.
 * 2) Heat the olive oil in a frying pan, and add ⅓ cup (80 g) sugar.
 * 3) Stir continuously until the sugar begins to brown. Remove from heat.
 * 4) The sugar will continue to brown for a few more minutes, creating a thick caramel.
 * 5) Add the caramel to the noodles.
 * 6) Add the sugar, eggs, cinnamon, pepper, and raisins. Stir.
 * 7) Bake in a pan at 350°F (180°C) until the top begins to brown (about 40 minutes).

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Template talk:SideBox

This is just a quick and dirty template for being able to set a message apart from the main text of an artical. The template displays the argument text in a grey-shaded box on the left-hand side of the screen. Box is 300px wide, and text is centered inside. --Whiteknight (talk)(projects) 16:27, 5 May 2006 (UTC)

title: Template talk:SideBox


text:
User talk:Domina~enwikibooks

Votes for undeletion
A book to which you have contributed, namely BDSM was deleted and is now listed at Votes for undeletion. It has been temporarily restored so people who have not seen the book can intelligently discuss whether Wikibooks want to keep the book. You may want to join the discussion. --JMRyan T E C 17:07, 5 May 2006 (UTC)

Your account will be renamed
Hello,

The developer team at Wikimedia is making some changes to how accounts work, as part of our on-going efforts to provide new and better tools for our users like cross-wiki notifications. These changes will mean you have the same account name everywhere. This will let us give you new features that will help you edit and discuss better, and allow more flexible user permissions for tools. One of the side-effects of this is that user accounts will now have to be unique across all 900 Wikimedia wikis. See the announcement for more information.

Unfortunately, your account clashes with another account also called Domina. To make sure that both of you can use all Wikimedia projects in future, we have reserved the name Domina~enwikibooks that only you will have. If you like it, you don't have to do anything. If you do not like it, you can pick out a different name.

Your account will still work as before, and you will be credited for all your edits made so far, but you will have to use the new account name when you log in.

Sorry for the inconvenience.

Yours, Keegan Peterzell Community Liaison, Wikimedia Foundation 23:10, 17 March 2015 (UTC)

Renamed
 This account has been renamed as part of single-user login finalisation. If you own this account you can |log in using your previous username and password for more information. If you do not like this account's new name, you can choose your own using this form after logging in: . -- Keegan (WMF) (talk) 04:54, 19 April 2015 (UTC)

title: User talk:Domina~enwikibooks


text:
Template:GNU C Compiler Internals/When to Instrument 4 1

 * Add new function and type declarations in hook gem_c_common_nodes_and_builtins.
 * Instrument an AST after it is parsed in hook gem_finish_function.
 * Modify attributes of a declaration in hooks gem_start_decl and gem_finish_decl. Let us say we would like to replace local array declarations char arr[10] with a heap array char *arr=(char*)malloc(10);

void l2h_start_decl(void *p_decl, void *p_declspecs, init initialized, void *p_attr) { struct c_declarator *decl = *((struct c_declarator**)p_decl); if (current_function_decl == NULL_TREE) return; if (decl->kind == cdk_array) { decl->kind = cdk_pointer; decl->u.pointer_quals = 0; } }

void l2h_finish_decl(tree decl, tree *init, tree spec) { ...   gem_find_symtab(&t_malloc, "malloc"); BUILD_FUNC_CALL1(t_call, t_malloc, build_int_cst(NULL_TREE, size), NULL_TREE); *init = build1(NOP_EXPR, build_pointer_type(char_type_node), t_call); DECL(decl) = build_int_cst(NULL_TREE, 0); // if this field is NULL the init is ignored }

 * Replace function call with a proxy function


text:
Template:GNU C Compiler Internals/When to Instrument 3 4

 * Add new function and type declarations in hook gem_c_common_nodes_and_builtins.
 * Instrument an AST after it is parsed in hook gem_finish_function.


text:
The Art of Cities/Transportation

Roads and Streets
These two simple transportation thoroughfares are arguably the most important in any city. Streets are mainly quiet residential streets, and roads are usually city-centre trunk routes. These are the purposes which roads and streets are given in the "definitions" below.

Streets (to the left) are the small, usually residential routes which are never too congested. They often come in the form of cul-de-sacs (streets with a dead end). They are almost always unmarked and are commonly separated from the pavement by a narrow strip of grass or trees. Another notable feature about streets is that, at junctions, the corners are much more curved than roads, making turning much easier for vehicles. Often, they are four car-widths wide: two widths for opposing traffic and two more for cars to park on either side against the curb.

Roads (to the right) are typically wider and busier than streets. They often contain multiple lanes of traffic in either direction. Where streets have stop signs to control traffic, roads have signals using a system of lights to alert drivers when to cross an intersection. These lights are used to increase efficiency of traffic flow.

title: The Art of Cities/Transportation


text:
User:Tchakkazulu/Contact

Contact information:

title: User:Tchakkazulu/Contact


text:
User talk:Keytotime

A-level Intergration
Some syllabi have intergration in C1, others have it in C2. According to the introduction we are following the OCR syllabus, which introduces Intergration in C2 not C1. Aleksev 18:02, 5 May 2006 (UTC)

re: A-level Mathematics Completing the square form.
Our class learnt the form $$a(x+d)^2 + e$$ for completing the square, and that's also the form used in the (OCR endorsed) textbook. Hope that helps. --Krackpipe 15:09, 27 May 2006 (UTC)

Vandalism
Hey, thanks for telling us about the vandal on WB:VIP. I am almost done reverting and deleting all his/her work. In the future, do not blank a page a vandal created because then it's a little bit harder to catch his/her edits in one swoop. Thanks. -within focus 23:25, 11 October 2006 (UTC)

Tagging merged pages for deletion...
Hi,

When you merge 2 pages that have multiple contributors, it's really better to have the edit history merged as well. I'm not sure how many you did, so far I only saw A-level_Mathematics/C3/Natural_Logarithms_and_Graphs. If you could let me know what page that was merged to, I'll be happy to merge the histories for you (only admins can do it, but it only takes a few seconds, and we're really supposed to do that in compliance with the GFDL). If there are other pages you merged, let me know about them too (you should merge the content first via copy-paste, just don't put them up for deletion, but rather request a history merger). -- SB_Johnny | talk 20:05, 12 October 2006 (UTC)

 * Huh... had to make a template: use to mark pages for this. -- SB_Johnny  | talk 20:12, 12 October 2006 (UTC)

Wikibooks Newsletter, Volume 1
(Wikibooks gazette home | Discuss | Bulletin board | Subscription list)

This is a short newsletter that is being distributed to all active wikibookians. You are getting this message because you are recognized as an established contributor to the project. This newsletter will be distributed on a regular basis to help share news, information, and tips. It comes from a bot account, User:The Staff. User:The Staff is currently operated by a team of wikibooks admins, the complete list of which is available on the user page of the bot. If you would like to not receive this newletter anymore, please remove your name from the list at Active wikibookians.

The work you do at Wikibooks is greatly appreciated. However there are plenty of other opportunities for you to get involved and help us to create a thriving Wikibooks community. We are sure that there are things we can do to help you and your understanding of Wikibooks and similarly there are certainly things you could do to help Wikibooks become a better place.

We would like to ask all wikibookians to add the Bulletin Board to your watchlists. The Bulletin Board is a fast and easy way for wikibookians to communicate important news and events to the entire community. If you have important news to share with the community, you can feel free to add your own entry to that page.

If you have general questions or comments about Wikibooks, you are welcome to post a message on The Staff Lounge, a free discussion area. Your input would also be welcomed in the Votes for Deletion and Requests for Adminship discussion pages. These pages are all active discussion areas that help to shape the Wikibooks community as a whole.

Sometimes it is easy to forget that the Wikibooks community is much larger and more diverse then the people who work in a single book, or on a single bookshelf. Hopefully, together we can all make Wikibooks a better place, and a more valuable educational resource.

The Staff 04:16, 19 December 2006 (UTC)

S1 help?
I was wondering if you would like some help on the S1 / S2 sections in the A-level OCR textbook collection. I've just finished those (along with C1,C2, FP1 and D1, if any assistance is desired). I've added a little to S1 already, about combinations and Permutations, and would like to be able to continue to help.

Acted on you merge request
Content of Complex Analysis Handbook is now merged on the Complex Analysis book. Take a look to see if something can be improved. --Panic (talk) 17:30, 11 July 2010 (UTC)

title: User talk:Keytotime


text:
Category:Cookbook pages with recipe lists

__HIDDENCAT__


text:
Georgia Water/Laws/Water Supply Act

 Georgia Water Supply Act (Reservoir Construction), O.C.G.A. §§ 12-5-470 to 482

General Description
This Act gives the Department of Natural Resources the authority to build water supply reservoirs. It authorizes DNR to acquire property and contract with local governments to begin and maintain reservoir projects that will sell and distribute water supply to local counties and municipalities. The Act specifies the powers of DNR and the relationship with local governments. The Act makes it the duty of DNR to select the site for such projects but provides for checks on DNR powers.

title: Georgia Water/Laws/Water Supply Act


text:
Georgia Water/Laws/Coastal Management Act

 Georgia Coastal Management Act, O.C.G.A. § 12-5-320

Summary of the Act
“The Coastal Management Act provides enabling authority for the State to prepare and administer a coastal management program. The Act does not establish new regulations or laws; it is designed to establish procedural requirements for the Department of Natural Resources to develop and implement a program for the sustainable development and protection of coastal resources. It establishes the Department of Natural Resources as the State agency to receive and disburse federal grant monies. It establishes the Governor as the approving authority of the program and as the person that must submit the program to the federal government for approval under the federal Coastal Zone Management Act. It requires other State agencies to cooperate with the Coastal Resources Division when exercising their activities within the coastal area.” Department of Natural Resources, Comprehensive Wildlife Conservation Strategy, Appendix G


text:
Georgia Water/Laws/Coastal Marshlands Protection Act of 1970

Coastal Marshlands Protection Act of 1970, O.C.G.A. § 12-5-280

Summary of the Act
“This legislation created the Coastal Marshlands Protection Committee which grants, denies, revokes, and amends all permits provided for by the Act and details the process to handle grievances of a party in relation to any rules or regulations adopted by the Board of Natural Resources. The Act outlines the powers and duties of the DNR and the Board of Natural Resources as to coastal marshlands. Marshlands may not be filled, drained, dredged, or otherwise altered without a permit from the committee. The Act indicates the process for obtaining a permit and explains the points reviewed by the committee prior to issuing or denying a permit. It authorizes the inspection of marshlands by officers and conservation rangers of the DNR to verify compliance with the rules, regulations, and permits, and enforcement in the case of noncompliance.” Department of Natural Resources, Comprehensive Wildlife Conservation Strategy, Appendix G


text:
Georgia Water/Laws/Land Conservation Act

Georgia Land Conservation Act, O.C.G.A. § 36-22-1

Summary of the Act
“Passed by the Georgia legislature in 2005, this law promotes land conservation by providing funds to state and local governments and encouraging partnerships with the private sector. The law also establishes the Georgia Land Conservation Revolving Loan Fund that will be managed by the Georgia Environmental Facility Authority (GEFA), which will provide a variety of funding options by which conservation easements or fee simple interest can be purchased. Operations of the fund and the authority are overseen by the Georgia Land Conservation Council, which is responsible for reviewing all project proposals and making recommendations for the distribution of funds. The act directs Georgia DNR to establish a land conservation program consistent with these purposes, to work with local governments to identify and review land conservation projects, and to maintain a geographic information system designed to serve as a comprehensive database of land protection activities. It also directs the Department to work with the Georgia Forestry Commission, State Soil and Water Conservation Commission, University System of Georgia Cooperative Extension Service and others to provide information and technical support to facilitate land conservation projects. Nongovernmental organizations are also encouraged to provide education to public and private sectors and to partner with counties, cities, and the Department on land conservation projects.” Department of Natural Resources, Comprehensive Wildlife Conservation Strategy, Appendix G


text:
Georgia Water/Laws/Groundwater Use Act

'''Groundwater Use Act, [http://www.legis.state.ga.us/cgi-bin/gl_codes_detail.pl?code=12-5-90 O.C.G.A. §§ 12-5-90 et. seq.]'''

General Description
"Groundwater withdrawals of greater than 100,000 gallons per day require a permit from the Environmental Protection Division. Permit applications that request an increase in water usage must also submit a water conservation plan approved by the Director of Environmental Protection Division (O.C.G.A. 12-5-96). The Environmental Protection Division has prepared a comprehensive groundwater management plan for coastal Georgia that addresses water conservation measures, protection from saltwater encroachment, reasonable uses, preservation for future development and economic development issues. The Memorandum of Agreement with the Environmental Protection Division ensures that permits issued under the Groundwater Use Act must be consistent with the Coastal Management Program." Department of Natural Resources, Comprehensive Wildlife Conservation Strategy, Appendix G

Specific provisions of the Act

 * Reasonable Use: Before issuing a permit, EPD will evaluate the reasonableness of the use by applying the criteria listed in the statute, including the number of persons using the water source; the nature, severity, or duration of any impairment adversely affecting availability for other users; any injury to public health, safety or welfare; the kinds of activities proposed; the importance and necessity of the uses and the extent of any injury caused to other water uses; diversion from or reduction in flows in other watercourses or aquifers; prior investment in land; and other relevant factors. § 12-5-31(e).

 * Duration: Municipal and industrial permits are issued for a term of 10 to 50 years, after which they must be renewed. Farm permits are issued for an unlimited term.

 * Quantity: Municipal and industrial permits are issued for a specific quantity determined by reasonable use. Farm permits issued after 1991 also have defined quantities.  Farm permits issued before 1991 are based on pump capacity as of July 1, 1988.

 * Revocation and Modification: Municipal and industrial permits can be revoked by EPD for extended periods of nonuse. Farm permits cannot be revoked after an initial use, though farm permits can be revoked if water was never withdrawn.

 * Transfers: Water permits are not transferable, except that farm permits may be transferred along with the accompanying land.

title: Georgia Water/Laws/Groundwater Use Act


text:
Georgia Water/Laws/Surface Water Use Act

Surface Water Use Act, O.C.G.A. § 12-5-31

General Purpose
Large water withdrawals are regulated by Georgia EPD through a water permit system based on the concept of reasonable use. Any user withdrawing or diverting more than 100,000 gallons-per-day is required to obtain a permit from EPD.

Reasonable Use
Before issuing a permit, EPD will evaluate the reasonableness of the use by applying the criteria listed in the statute, including the number of persons using the water source; the nature, severity, or duration of any impairment adversely affecting availability for other users; any injury to public health, safety or welfare; the kinds of activities proposed; the importance and necessity of the uses and the extent of any injury caused to other water uses; diversion from or reduction in flows in other watercourses or aquifers; prior investment in land; and other relevant factors. § 12-5-31(e).

Specific provisions of the Act

 * Duration: Municipal and industrial permits are issued for a term of 10 to 50 years, after which they must be renewed. Farm use permits are issued for an unlimited term, except in the Flint River Basin in which farm use permits issued after March 2006 have a term limit of 25 years.

 * Quantity: Municipal and industrial permits are issued for a specific quantity determined by reasonable use. All Farm use permits are based on pump capacity as of July 1, 1988.

 * Revocation and Modification: Municipal and industrial permits can be revoked by EPD for extended periods of nonuse.  Farm permits cannot be revoked after an initial use, though farm permits can be revoked if water was never withdrawn.

 * Transfers: Water permits are not transferable, except that farm permits may be transferred along with the accompanying land.


text:
Georgia Water/Laws/Flint River Drought Protection Act

Flint River Drought Protection Act, O.C.G.A. § 12-5-540

Summary of the Act
The purpose of this Act is to maintain in-stream flow in times of drought by providing incentives for farmers to take acres out of irrigation. It allows EPD to pay farmers to stop irrigating. After a drought is declared, EPD can hold a voluntary seller’s auction, allowing farmers to offer prices per acre at which they are willing to stop irrigating. If the target is not achieved, EPD has authority to make further reductions on a “non-voluntary” basis.

History of the Act
A 2001 auction eliminated irrigation from surface water on 33,101 acres at an average price of $135 per acre and a total cost of $4.5 million. The funding came from Georgia’s share of the tobacco settlement money.


text:
Georgia Water/Laws/Comprehensive Statewide Water Management Planning Act

Comprehensive Statewide Water Management Planning Act, O.C.G.A. §§ 12-5-520 to 525

General Summary
This Act asks EPD to develop and propose a comprehensive statewide water management plan. This Act doesn’t change any water laws or policies; instead, it merely asks EPD to develop a state plan, which will then be considered by the legislature in 2008. Any proposed changes to water laws or policies will be considered in the planning process.

Policy
The policy behind the Act states, “Georgia manages water resources in a sustainable manner to support the state’s economy, to protect public health and natural systems, and to enhance the quality of life of all citizens.” The EPD plan should be consistent with this statement.

Specific provisions of the Act

 * The Water Council: The Water Council, created by this Act, consists of various legislative members and appointments and the heads of state departments with water related responsibilities. The Water Council is responsible for providing input in the planning process, coordinating input from various state departments, and ultimately approving the version of the plan that will be submitted to the legislature for final approval.  EPD must present a draft plan to the water council by July 1, 2007.

 * Public Participation: EPD must solicit input from stakeholders and the public in the development of the water plan. Relevant stakeholders include businesses, nonprofit organizations, local governments, and others.

 * Process for Plan Adoption and Approval: The water plan will be presented for approval by the General Assembly by the 2008 legislative session. There are four possible ways for the water plan to go into effect:
 * The General Assembly approves the proposed plan
 * If the General Assembly rejects the first proposed plan, the Water Council may submit alternative plans through the 20th day of the session
 * The General Assembly can enact its own version of a plan, or
 * If no plan is approved or enacted by the legislature, then the initial version of the first plan presented to the General Assembly will automatically take effect.


text:
Georgia Water/Laws/Environmental Policy Act

Environmental Policy Act, O.C.G.A. § 12-16-1

Summary of the Act
This Act requires the State to prepare an environmental effects report for any state funded construction project that may have a significant adverse effect on the environment. This requirement applies to “land disturbing activities,” which includes scraping, clearing, dredging, grading, excavating, or building a dam. It applies to government projects, projects funded by government grants, or municipal projects receiving more than $250,000 or more than 50% government funding, but it does not apply to agriculture or private developments.

Specific provisions of the Act

 * Environmental Effects Reports: If the project will have a significant effect on the environment, an environmental effects report must be prepared. The report should explain any environmental impacts, including effect on water quality and quantity, and also environmental effects that cannot be avoided, possible alternatives, and proposed mitigation.
 * Openness to the Public: The government agency must make the environmental effects report available to the public, and notify the public about the project. If at least 100 people request a public hearing, then the state must hold a hearing a take public comments.


text:
Georgia Water/Laws/Local Government Public Works Construction Law

Georgia Local Government Public Works Construction Law, O.C.G.A. § 36-91-1

This Chapter sets forth the law for when private construction companies bid on public works projects. The state or local government is required to publicly advertise the contract opportunity before awarding a contract. All contracts must be in writing and must be available for public inspection.


text:
Talk:Famous Theorems of Mathematics/Four color theorem

Minumum Counter Example
Is it really appropriate for the "amateur" to consider the mininum counter-example approach as a format for proving the 4CT? How can we compete with the experience and sophisticated computing power of the professionals?

Jillbones 18:52, 5 May 2006 (UTC)

Simple math tells us that the fully triangulated planar graph for which Grinberg's graph is the dual would have only 24 vertices. Does such a graph exist?

Jillbones 01:26, 12 March 2007 (UTC)

"The dual of a fully-triangulated planar graph is a cubic planar graph. Cubic means that every vertex has 3 edges. However, not every cubic planar graph has a Hamiltonian cycle -- if it did it would prove the Four Color Theorem."

Can anyone explain why this is true? In your explanation, kindly state how each graph was created and which feature of the graph is being colored; ie (face, edge or vertex). For instance, in the map, it is the faces that are being colored. If, in the graph equivalent, the colorability of the faces is also being considered, describe how such a graph equivalent is achieved. If, in the graph equivalent; the colorability of the vertices is being considered; describe how that graph equivalent was generated.

Jillbones 22:33, 15 March 2007 (UTC)

 * Ok. We have a fully-triangulated planar graph G, and are trying to four-colour its vertices. This is equivalent to trying to four-colour the faces of the dual graph, which is cubic. A standard trick involving the Klein four group means that four-colouring the faces of a cubic planar graph is equivalent to three-colouring the edges. But if any cubic graph had a hamiltonian cycle, then we could easily three-colour the edges: just alternate red, blue along the hamiltonian cycle, and colour the remaining edges green. 131.111.8.96 10:47, 7 June 2007 (UTC)

This works iff the faces of the dual have a one-to-one correspondence with the vertics of G. Fortunately, this is always true whenever G is fully triangulated. By design, G itself is the dual of a map or graph. The generating map is 3-regular and the generating graph is \ a cubic planar graph. If M is the generating original map or graph, then G is the dual of M and M is the dual of G.

This means that if M is a 3-regular map or a cubic planar graph and M is 3 edge colorable. then M is 4 face colorable and the 4CT is true. You do not need the "triangulation"!

Of course, not all cubics have a "triangulation" for a dual!


text:
User:Tchakkazulu/Interests

My interests lie in the following areas:

 * Math
 * Algebra
 * Abstract Algebra
 * Group theory
 * Rings
 * Galois theory
 * Geometry
 * Euclidian Geometry

 * Computer Science
 * Programming
 * Functional Programming
 * Haskell

As I learn more at university, this list might change. I'm currently a third year's student, so that'll definitely happen.

title: User:Tchakkazulu/Interests


text:
User:Tchakkazulu/Subpages

List of subpages: Contact Information | Interests Page | Subpages

title: User:Tchakkazulu/Subpages


text:
Talk:Movie Making Manual/Crew Contract

This is not a crew contract. This is a personal release for on screen talent. There is no mention of crew position. Do not use this for crew contracts.

title: Talk:Movie Making Manual/Crew Contract


text:
Haskell/More on datatypes

Enumerations
One special case of the  declaration is the enumeration — a data type where none of the constructor functions have any arguments:

You can mix constructors that do and do not have arguments, but then the result is not called an enumeration. The following example is not an enumeration because the last constructor takes three arguments:

As you will see further on when we discuss classes and derivation, there are practical reasons to distinguish between what is and isn't an enumeration.

Incidentally, the  datatype is an enumeration:

Named Fields (Record Syntax)
Consider a datatype whose purpose is to hold configuration settings. Usually, when you extract members from this type, you really only care about one or two of the many settings. Moreover, if many of the settings have the same type, you might often find yourself wondering "wait, was this the fourth or fifth element?" One way to clarify is to write accessor functions. Consider the following made-up configuration type for a terminal program:

You could then write accessor functions, such as:

You could also write update functions to update a single element. Of course, if you add or remove an element in the configuration later, all of these functions now have to take a different number of arguments. This is quite annoying and is an easy place for bugs to slip in. Thankfully, there's a solution: we simply give names to the fields in the datatype declaration, as follows:

This will automatically generate the following accessor functions for us:

This also gives us a convenient update method. Here is a short example for a "post working directory" and "change directory" functions that work on s:

So, in general, to update the field  in a value   to, you write. You can change more than one; each should be separated by commas, for instance,.

It's only sugar
You can, of course, continue to pattern match against s as you did before. The named fields are simply syntactic sugar; you can still write something like:

But there is no need to do this.

Finally, you can pattern match against named fields as in:

This matches the variable  against the   field in the   and the variable   against the field. These matches will succeed, of course. You could also constrain the matches by putting values instead of variable names in these positions, as you would for standard datatypes.

If you are using GHC, then, with the language extension, it is also possible to use this form:

It can be mixed with the normal form like this:

(To use this language extension, enter  in the interpreter, or use the   pragma at the beginning of a source file, or pass the   command-line flag to the compiler.)

You can create values of  in the old way as shown in the first definition below, or in the named field's type, as shown in the second definition:

The first way is much shorter, but the second is much clearer.

WARNING: The second style will allow you to write code that omits fields but will still compile, such as:

Trying to evaluate the unspecified fields will then result in a runtime error!

Parameterized Types
Parameterized types are similar to "generic" or "template" types in other languages. A parameterized type takes one or more type parameters. For example, the Standard Prelude type  is defined as follows:

This says that the type  takes a type parameter. You can use this to declare, for example:

The  function takes a list of birthday records and a string and returns a. The usual interpretation of such a type is that if the name given through the string is found in the list of anniversaries the result will be  the corresponding record; otherwise, it will be. is the simplest and most common way of indicating failure in Haskell. It is also sometimes seen in the types of function arguments, as a way to make them optional (the intent being that passing  amounts to omitting the argument).

You can parameterize  and   declarations in exactly the same way. Furthermore you can combine parameterized types in arbitrary ways to construct new types.

More than one type parameter
We can also have more than one type parameter. An example of this is the  type:

For example:

In this example  indicates how many groups you would have if you paired off a certain number of people for your activity. It can also let you know if you have too many people for your activity or if somebody will be left out. So  will return either an Int representing the number of groups you will have, or a String describing the reason why you can't create your groups.

Kind Errors
The flexibility of Haskell parameterized types can lead to errors in type declarations that are somewhat like type errors, except that they occur in the type declarations rather than in the program proper. Errors in these "types of types" are known as "kind" errors. You don't program with kinds: the compiler infers them for itself. But if you get parameterized types wrong then the compiler will report a kind error.

title: Haskell/More on datatypes


text:
Category:Israeli recipes

Recipes from Israel.

title: Category:Israeli recipes


text:
Cookbook talk:Adobo Chicken (Philippine)

An alternative: My experience of traditional Filipino Adobo has been that it does not contain either potato, apple cider vinegar or blackbean paste. Agreed, any meat (whether chicken or pork or a combination of both) for Adobo should always contain bones, but authentic Tagalog adobo is prepared with Datu Puti (a form of white rice-wine vinegar) - the flavour is softer than regular vinegar - (use 1 cup Datu Puti and 1 cup water), add a splash of soy (for colour) and the same amount of fish sauce, several cloves of garlic, bay leaves and black pepper corns. No need to brown meat first. Just put all in a saucepan, cover and simmer gently until the liquid is reduced by half. Remove the meat and garlic (save the liquid) and fry gently until it's brown and crispy on the outside. Pour juices over the meat and serve with steamed rice. —The preceding unsigned comment was added by 211.29.7.207 (talk • contribs).

I totally agree that traditional Philippine adobo does not contain either potatoes or blackbean paste -- I wonder what region in the Philippines the author came from. I grew up in Manila eating adobo, and my Mom is a fantastic cook, and have never ever eaten (or cooked) adobo with potatoes and black bean sauce! I find apple cider vinegar too strong, so I normally use a lighter variety - if you can't find Datu Puti, you may dilute the apple cider vinegar with a bit of water. I also like to add a teaspoon or so of a good white wine, for added flavor. To comment on using 1 cup vinegar and 1 cup water: that sounds like too much -- you might end up have adobo soup, unless you're using tons of meat. Also, some people prefer dry adobo, which is achieved by frying the meat in a little oil after it has been tenderized by simmering and not adding back the simmer sauce; or a wetter version, when you add back some or all of the simmer sauce after frying the meat. Serve with plenty of steaming white rice. Yum! [ChefMom]

Adobo in the Philippines is surely masarap(delicious)Morphine54 (talk) 03:58, 2 December 2010 (UTC)

"Datu Puti" is not a type of vinegar, but a brand name of vinegars (they make several types) commonly available in the Philippines. Generally, household vinegars are 5% acidity (4% for Japanese rice vinegar), and in my family, we have always used a 50/50 mix of 5% vinegar to Kikkoman koikuchi shoyu. Patis has always been optional in my house, but always Rufina from Malabon, Metro Manila, when we use it. These days, I use Datu Puti Premium Cane Vinegar, since it is easily available now in the US, or sometimes I like to use Datu Puti's Sukang Iloco for an interesting flavor. Try different vinegars for different flavors! There is more than one suka (vinegar) in the world!

There are as many styles of adobo as there are Filipino cooks! Some prefer adobong puti (white adobo, made with salt instead of soy sauce or patis), some prefer it made with patis, some prefer it made with soy sauce. Some like it dry, some like it soupy (the tradition in my house, which I am told is common to the Manila region), some like it browned, some don't. Some like it "sa gata" (with coconut milk), and some don't. Some like it with a touch of sugar or fruit added, some like it with a bit of siling (hot pepper), or an onion in the pot. Personally, I make it different ways on different days, depending on my mood or the mood of my family.

I must say, though, that the recipe page as it stands right now calls for a very small amount of garlic, only four cloves, and I have always used an entire head (about 12 cloves) for that much chicken. 6-8 pieces is a whole chicken. Otherwise the current recipe has good proportions: 1/3 c. vinegar to 1/4 c. soy sauce, 1-2 bay leaves, 1/2 tsp. peppercorns. That's a good recipe, although in my family, we'd just simmer it until the chicken falls off the bone, and eat it just like that, with lots of sauce to pour over our rice. I must have missed the potatoes and black bean sauce version. LOL

Romy Dorotan, chef of Cendrillon and Purple Yam in New York City, recommends apple cider vinegar for pork adobo, and I very much agree that this works very well. All I know is, my father used to tell everyone I made the best adobo ever. Kind of embarrassing in front of the Filipino family, but everyone likes my cooking, so maybe he's right. I've never met a person that disliked my adobo. In fact, invariably, people rave about it. I like to serve it with roasted pineapple and steamed long grain white rice. [Gemma Seymour-Amper]


text: User:Tchakkazulu/Footer Template

title: User:Tchakkazulu/Footer Template


text:
Blender 3D: HotKeys/Key/Z

Z
 * CTRL+Z - Undo
 * SHIFT+CTRL+Z - Redo
 * SHIFT+CTRL+Z - Redo

title: Blender 3D: HotKeys/Key/Z


text:
Cookbook talk:Roast Beef

TimWright: I just noticed that this recipe is identical (word for word) with part of the recipe on this page: http://www.elise.com/recipes/archives/000457roast_beef.php - do we have a plagerism issue here?

Word for word ??? You clearly can't read as there is not one single sentence which is the same in my recipes as in the one you highlight

Oh, and while we are on the subject, you also cant spell. Plagiarism.

You come over all "johnny foreigner" when it comes to length measurements, and yet you use centigrade rather than fahrenheit. A true Englishman - merrily confused! Anyway, I'm about to try this.

Hi, this is a great recipe, and the writing makes for a bit of character... but it doesn't sound done. After I put it in the roast, do I just leave it and go to church, and then come back and it would be done? If this is so, it should say so in the article, or at least a ballpark estimate of how long it'll take. Thanks for the recipe; I'll try this soon. --Mathwizard44 (talk) 08:23, 9 January 2009 (UTC)

Cleanup
I've added proper headings to this cookbook and removed some of the more casual language. Also when you add comments to this talk page please sign them with ~ so we know who wrote what. I've also removed some terms like "2.5cm to Johnny Foreigner". This term is not polite and certainly not true considering that only 2 countries out of 196 countries in the world still use imperial measurements. Xania talk 15:21, 31 December 2006 (UTC)

''Why are the Wikipedia self-appointed Gestapo always so agressive? Correct and comment on articles to get them to conform to the Wikipedia ideal, by all means, but can't it be done politely !!'' "This is awful".....Who says ? "Not polite".. It is perfectly polite. "Name dropping"... absoloute rubbish. And who on earth wrote that bit about not putting Fahrenheit temperatures? No one uses Fahrenheit in cooking, and if they do, they should get a life !!

Given this is meant to be a cookbook and not a work of gravitas I wrote this recipe in a manner that might provide some amusement to those that read and subsequently tried it. The feedback has been amazing... but I also phrased it thus to prove or disprove the notion that Wikipedia is run by the pedantic and self righteous for the pedantic and self righteous. I hoped it wasn't.. but was wrong. Name dropping ? For goodness sake... all I am doing is giving recognition that that particular improvement to the recipe was someone else's idea !! I don't actually KNOW Heston Blumenthal !

And lastly why don't you go and slag off my recipe for Roast Lamb as well, if you have nothing else to do.... here it is... http://en.wikibooks.org/wiki/Roast_Lamb... but do yourself a favour, and try it first ! Peterkirchem 23:02, 10 January 2007 (UTC)

 * G'day Peter. It seems to me that you are the one being aggressive here. Please have a cup of tea and calm down, then look at the following.

 * Firstly, it's better if you are logged on when you make edits, and especially when you add comments on talk pages. This provides a clear trail of who made the edits, and allows you to easily sign your comments: just add the following at the end of your comments on talk pages and we'll know who you are: ~

 * Secondly, It was I, not the Irishman, who put the cookwork tag on this recipe. I did that because I thought it was poorly formatted and sounded like a glory piece, rather than a recipe. It also appeared to have been copied and pasted from a Microsoft Word document, complete with unnecessary line spacing and inappropriate ellipses (which I cleaned up). I left the tag there because there was (still is) more work to be done to make this recipe look like it is a part of the Cookbook. However, I was probably being a little too harsh, and have amended the tag text.

 * It is true that this is not Wikipedia, and there is much greater flexibility on what can be written here. However, there are still some guidelines that apply – I suggest that you take a few moments to read them: WB:PAG, Cookbook:Policy

 * Finally, please don't take offence if someone sees fault in something you put up on Wikibooks. Remember that Wikibooks is here for everyone, not just as a publishing point for you. Please join us in making Wikibooks more complete. Webaware 23:29, 9 January 2007 (UTC)

My point is the frustration at having had quite a few comments from people who have both tried the recipe, and been amused by it's structure and have contacted me to say so - as I use my own, full name and do not hide behind a pseudonym, they were able to trace me through Google - seems to me to have fulfilled the purpose of a food recipe, even if it does not adhere stricly to the Wikipedia ideal. I have no idea how to set this out.

It has not been copied from anywhere and every last word and detail has been written and invented by me. I laid it out in a way I considered made it clear and easy to follow. The way it is laid out now makes it harder to follow... one does tend to print out recipes found on the net, rather than have a computer on one's worksurface...

I have no idea what a glory piece is, but assume it suggests that for some reason I wrote the recipe for my own gratification. What an absurd notion. The reference to Peter is purely to differentiate it from other recipes for the same thing people may put up and also to take a degree of reponsability for its content.

But at least you had the decency to explain your comments. I am afraid my own, and my friends' experiences with other Wiki editors have been quite shocking given their apparent air of graceless superiority, and makes us feel we never want to have anything to do with it again.

Your last paragraph seems to me to be a contradiction. You say Wikipedia is not here as a publishing point for its contributors, and in the next sentence encourage me to make Wikibooks more complete.

COuld it be that Wikicookbook needs to be a little less dogmatic in what it demands of its contributors? It appears I am not the only renegade on the team, but basically our intentions are good... cookery is art, and you know what a pain artists can be !!

Peterkirchem 22:44, 10 January 2007 (UTC)

 * G'day Peter. I can quite understand your frustration, as I have had problems myself. In particular, there can be a sort of policy tunnel vision, both here and on Wikipedia, where the spirit of the policy is forgotten but the letter of the policy is upheld – sometimes to the detriment of the respective projects. Fortunately, that is less the case here than on Wikipedia.

 * Please don't read into what I wrote, that I am accusing you of copying someone else's recipe. What I said was that it appeared to have been copied and pasted from a Microsoft document, thus requiring some additional cleanup. This is nearly always the case, because Microsoft editors nearly always make a mess when text is copied from them. That isn't to say don't use them – merely that you need to check what was brought across, and cleanup the mess as you go.

 * As to the notion of a glory piece being absurd, you'd be surprised what people get up to on the Internet. I see nothing wrong in taking pride from publishing one's favourite personal recipe, by the way, but there are some books on this site... anyway, let's put that one to the side!

 * I see no contradiction in my last paragraph. Wikibooks is here for all of us, not for each of us to get on our soap boxes – that is all that I meant when I said not just as a publishing point for you. When contributing to Wikibooks, one has to bear in mind the readers, and also the accompanying books. The guidelines help to maintain some sense to what is published here. They are not set in stone, but it does help to follow them at least a little. Recipes that look like recipes are easier to scan when looking for what ingredients need to be bought, for example - and that was one reason that I tagged your recipe with.

once I have learned how to work all the templates etc.
 * As for cookery being art, and artists being a pain, well ... I dare say that I resemble that remark :-) Webaware 00:39, 11 January 2007 (UTC)

 * No, sorry, YOU didn't accuse me of plagiarism, that fellow Wright did at the top of the discussion page, and I was only amused how on earth he might have reached such a conclusion when comparing my recipe with the one he makes reference to. Anyway, I am sure you have better things to do than pander to my rants, so I shall slowly Wikify my recipes, but need to learn how to utilse the templates etc first. You see ? I even learned where the ~ is on my keyboard and how to indent a line...

 * What is interesting though is that your attitude to my hot-headedness (not really, but I do enjoy being a little cantankerous on occasions!! Must be my age) has brought results, as opposed to the really quite virulent and condescending (and at times frankly bloody rude) attitude of many of the Wikipedia editors some of whom I have made a point of studying over the past few days.It seems ones based in the US are the absolute worst.

 * Is there a code of practise when dealing with with contributions that offend the Wiki code of presentation, as, contributors of more serious topics than roast beef, who may be genuine experts in their learned fields, who are then slated for their efforts by WIki staff because the presentation (as opposed to the content) does not fulfill the WIki ideal, must at times feel there is little point in contributing further, which, at least in my opinion, would seem to potentially erode the stature of WIkipedia as a whole. Btw.. Are you an Aussie?Peterkirchem 12:37, 12 January 2007 (UTC)

 * Conversation shifted to your talk page (in a minute...) Webaware 22:42, 12 January 2007 (UTC)

I have made quite a few minor changes in some of this wonderful recipe, just to improve clarity really. I have tried to collect the ingredients a bit more systematically in one section, so that people know what to get before they start cooking on a Sunday. Nothing worse than trying to find goose fat on a Sunday! I have tried to use metric and imperial measures and temperatures consistently throughout. I hope I haven't detracted from the spirit of this charming writing which has inspired me to make the recipe very soon! Some wonderful tips my mother never taught me! Should I include the traditional Yorkshire Pudding recipe in another page? SuW (talk) 06:35, 13 January 2008 (UTC)

A delightful edit ! Thank you so much ! It is so nice to see some editing which does not totally trash to original text, and is done so with such good grace. I personally cant stand Yorkshire Pudding (Despite a Grandfather who was Bishop of Bradford!) but, of course it should be included..!! Lol. There are loads of other recipes I have put it. Maybe we can start a partnership and come up with some really good ones. You never know, we could even write a cookbook together ! Peterkirchem (talk) 21:35, 16 January 2008 (UTC)

Name change from "Roast Beef" to "Roast Dinner"
I wanted to suggest chaning this recipe name from "roast beef" to "roast dinner" as the recipe outlines an entire roast dinner, not juse how to make a roast beef. Jamzze (discuss • contribs) 20:36, 17 July 2022 (UTC)

 * Actually, scrap this. I will nest "Roast Beef" under "Roast Dinner" so that other variations can be included, e.g. roast chicken, etc. Jamzze (discuss • contribs) 20:55, 17 July 2022 (UTC)

title: Cookbook talk:Roast Beef


text:
User:Xenon312

Heyya! I am Xenon, ph33r me. I am a cheerful leukemiac at the moment and i have no artistic taste. Currently I haven't really done a whole lot. Possibly added a page... Somewhere...

title: User:Xenon312


text:
User:Alejo2083

You can find me at my English Wikipedia user page.

title: User:Alejo2083


text:
WebObjects/Additional Resources/Authors

The following people have approved the use of his or her WebObjects mailing list posts when accompanied by the proper attribution. If you would like to reproduce a mailing list post onto the WebObjects Wikibook, please refer to this list prior to doing so. If you would like your own posts to be available, please add your name to this list.

 * Andrew Lindesay
 * Andrus Adamchik
 * Logan Allred
 * Pierre Bernard
 * Zak Burke
 * Ondra Cada
 * Alex Cone
 * mmalcolm Crawford
 * Travis Cripps
 * Lachlan Deck
 * Brendan Duddridge
 * Gavin Eadie
 * Pierre Frisch
 * Chuck Hill
 * David Holt
 * Geoff Hopson
 * Art Isbell
 * Ian Joyner
 * Kieran Kelleher
 * Anjo Krank
 * David LeBer
 * Francis Labrie
 * Paul Lynch
 * Jake MacMullin
 * Baiss Eric Magnusson
 * Sacha Michel Mallais
 * Joe Moreno
 * Guido Neitzer
 * Sigurður Anton Ólafsson
 * Thomas Pelaia II
 * Christian Pekeler
 * Arturo Perez
 * John Pollard
 * Mark Ritchie
 * Aaron Rosenzweig
 * Mark Ruggiero
 * Mike Schrag
 * Helge Staedtler
 * Thomas Termini/Bluedog
 * Jean-Francois Veillette
 * Jerry W. Walker
 * Robert Walker
 * Pierce T. Wetter III
 * Carlos Gonzalez
 * Timo Höpfner
 * Javier Romojaro

title: WebObjects/Additional Resources/Authors


text:
WebObjects/Web Applications/Development/Direct Connect

Overview
By default, both Xcode and Eclipse/WOLips will configure your application to use Direct Connect. When your WebObjects application launches, it listens on a particular port (assigned by the WOPort configuration option). Under a full-blown deployment scenario, this port is used by the mod_WebObjects adaptor or the WebObjects cgi-bin adaptor to communicate between Apache and your application. However, it's also possible to run in development completely on the Direct Connect port (i.e. without a webserver). In this configuration, one noteable difference is that all resources are served by the Direct Connect server as opposed to the Apache scenario where resources are served by Apache directly and your WebObjects application only handles application requests.

Warning - wotaskd relies on direct connect being enabled so that the adaptor can communicate with it. Do not globally disable direct connect on your servers. For example, if you disable direct connect from the WebObjects.properties file in the application server's home directory, you will prevent wotaskd from responding to requests on its assigned port.

Turning Off Direct Connect

 * Configure your Apache to use mod_WebObjects or the cgi-bin adaptor
 * Ensure wotaskd is running
 * Set WODirectConnectEnabled to false
 * Setup your WebServerResources folder so that it is reachable by Apache
 * Profit

Logan Allred
I've heard all the comments about Direct Connect being evil, and I've been bit many times by its quirks, but I'd like to know from those that eschew Direct Connect what their workflow is and how they benefit (especially if they use Eclipse/WOLips). I still use Direct Connect, mostly because I'm used to the workflow and have figured out most of the things that can go wrong by now. I like the fact that all of my development resources are all in one project and it seems I get some niceties in WOBuilder when using Direct Connect.

Maybe it's because most my projects focus mostly on data and not presentation (I have only a few graphics and an occasional stylesheet--though I'm beginning to use stylesheets more), and that I go back and forth between developing on Windows and Mac (so scripting can become a pain). My apps have not yet suffered because of the speed of loading graphics (far more the speed of database access).

It's not that I fear web servers, I'm just lazy :) and not used to a workflow where I have "split development" instead of "split deployment". How do you version and manage your web resources being in a completely different location than your development resources (do you use resource folders in Eclipse, or separate projects? or some other nice Eclipse feature I haven't learned about? manual copying?). How do you handle deployment across development/staging/production? How much do you have to customize or modify your projects?

I can definitely see on sites with heavy presentation or dedicated graphic designers where using the web server would be a real plus, but I'm usually on a small team of 2-4 developers with minimal presentation.

I'm sure there's a better workflow than I'm using, I'm curious what everyone else considers to be development and deployment best practices for WO. What am I missing out on?

Chuck Hill
First off, it is not just about images. It is about having the power of a real webserver and about avoiding problems that only appear when you move to running the app through a real web server. Think of things like:

 * caching, mod_expires is NOT your friend
 * HTTPS
 * SSI
 * Rewrite rules
 * headers only present when going through a web server

I'm sure you can think of more differences. I'd rather develop with all the services I will get in deployment and also find the problems that crop up _before_ the app has been in production for half a day! I prefer my pain to be at leisure, not in panic. And, at least on OSX, it is dead easy to get Apache going.

As for work flow, what work flow? Our "projects", as seen from the source repository, are a hierarchy of folders. One is for code and that is where the WO projects go. Another is DocumentRoot and that is where, well, the document root stuff goes. Other folders are for docs, design, tests, etc. It is easy enough to check each one out where it goes. If your images are mostly static, so much less to do. If they change a lot, then the designers etc. can check in and out what they need in a way very familiar to them without needing to puzzle over arcane things like an Eclipse project. Image updates to your local doc root happen the same way that code updates to your workspace does.

For deployment, we have scripts that do command line Ant builds of all the code,tar up all the various resources (doc root included), and just generally make an install package. Another script on the target server takes that package, untars it, and copies the bits where they need to go. I don't understand how having to do split installs makes this any easier.


text:
WebObjects/Web Applications/Development/WO Component/Binding Synchronization

WebObjects Wikibooks considered deprecated
Look at http://wiki.objectstyle.org/confluence/display/WO/Web+Applications-Development-WO+Component-Binding+Synchronization instead.

Overview
When you create a subclass of WOComponent, the default configuration is to have all of your bindings automatically synchronized. Binding synchronization is the process of getting and setting parent and children .wod file bindings during the request-response loop. While binding synchronization is very convenient, the one downside is that your binding get and set methods can be called multiple times (as many as six) during the request-response loop. As a result, you should be careful about potential performance problems inside of get and set methods. If you would rather avoid the potential performance issues, it is possible to disable automatic binding synchronization in your component by simply overriding the synchronizesVariablesWithBindings method to return false as in the below example:

public boolean synchronizesVariablesWithBindings { return false; }

If synchronizesVariablesWithBindings is false, you will use the valueForBinding(bindingName) and setValueForBinding(value, bindingName) methods to get and set the binding value manually.

WOComponentContent
Because of the way WOComponentContent works, binding is often "backwards" from your intution (often it ends up that your wrapper pushes its title value into your page instead of the other way around). One way to make your template wrapper component behave the way you expect is to turn off automatic binding synchronization:

public boolean synchronizesVariablesWithBindings { return false; }

public String pageTitle { return (String)valueForBinding("pageTitle"); }

Kieran Kelleher
Have a look at WOComponent API valueForBinding and setValueForBinding methods. In your subcomponent, you can define the API (jigsaw icon in WOBuilder. Use lazy initialization to pull bindings on demand. Subcomponents in general pull from parent and push into parent through bindings. Here is an example of a simple manual pull and push of a 'customer' binding:

public CTCustomer customer {   if (customer == null) { customer = (CTCustomer)valueForBinding("customer"); }   return customer; } public void setCustomer(CTCustomer newCustomer) {   customer = newCustomer; setValueForBinding(customer,"customer"); }

Also look at synchronizeVariablesWithBindings to turn on manual binding synchronization (recommended to synchronize on demand rather than 6 times or so through the R-R loop)

wojingo
If you use lazy initialization in your binding accessor methods as described above, you should also make the component stateless. If you do not make the component stateless you will find that your component may display incorrect values when used in a WORepetition. This situation occurs when the WORepetition's list is changed via a component action and null is returned. The existing nested component will be reused and the values in the original list will be displayed.

Make the component stateless and override its reset method, setting all instance variables to null. This will make the component behave as expected.


text:
Programming for Palm OS

 * Programming the Palm using SuperWaba
 * Programming the Palm using PRC-Tools
 * Using the PalmOS Emulator, POSE
 * Programming the Palm using C
 * PilRC - the PILot Resource Compiler
 * Small fonts

title: Programming for Palm OS


text:
Muggles' Guide to Harry Potter/Magic/Furnunculus

Overview
Furnunculus apparently causes whoever it hits to erupt in boils.

Extended Description
This is one of the classic duelling spells. Harry used it first in Harry Potter and the Goblet of Fire; he had been goaded into duelling with Draco. The spell hit Draco's Densaugeo jinx and ricocheted, hitting Goyle.

Analysis
In Harry Potter and the Goblet of Fire we learn that combining jinxes can have unexpected effects – apparently, Harry's Furnunculus curse combines with George's Jelly legs curse to afflict Crabbe with little tentacles all over his face. We can't be certain that the boils that afflicted Goyle in the earlier episode were the intended effect; the spell may well have been modified by hitting the Densaugeo spell. However, "Furnunculus" in Latin translates directly to "boil".


text:
WebObjects/EOF/Using EOF/Memory Management

Overview
Memory Management in Java is a bit of a black art. When combined with EOF, there are certain issues that you need to be aware of. In WebObjects 5.2, there was a major change to the memory management system in EOF that provided support for WeakReferences to EO snapshots rather than only relying on the previous system of reference counting. This provides for vastly superior memory performance under the same conditions with the same app in 5.2 and above, because there are many cases where references will be released by Java's memory system rather than be held onto by your EOEditingContext.

There is a large overlap between the content about Caching and Freshness and that of Memory Management. Both should be read to fully understand how caching and memory management should play a part in your application design.

General Issues
One important issue to consider prior to taking any drastic measures is whether or not your application really just requires more memory than you are giving it. By default, a Java Virtual Machine gives a Java application 64M of memory. This is not that much memory for an enterprise web application. You can adjust this by setting the "mx" flag on your VM at launch time (-Xmx256M would give you VM 256M of heap to work with instead of the default 64M). Other than just hunting aimlessly in your code, profiling your application is the only way to truly determine your application's memory situation.

The following profiling tools have been verified to work with WebObjects:
 * JProfiler ( http://www.ej-technologies.com/products/jprofiler/overview.html ) has explicit support for WebObjects. It can automatically update your WebObjects Application launch script to insert itself at runtime to allow you to remotely attach to the application and profile it.

Raw Rows
The use of Raw Rows can dramatically decrease your memory usage (and increase your application's performance) at the cost of convenience. This uses less memory than normal EO's, allows better support for fetch limits, and you can still promote them to full-blown EO's when need be. Check out the Raw Rows topic for more information.

Qualify your Fetches
If you are not careful when you fetch, you may bring in huge datasets. When you use an EOFetchSpecification, be mindful to specify the most restrictive EOQualifier that still returns the data you need. Otherwise, you will be potentially faulting in much more data than your application will use, and you decrease your overall application performance because of the data that must be transferred from your database.

Relationships from Enumerated Types to other EO's
It is very common to have EO's that represent "Enumerated Types". For instance, you might have a bug tracking system that has a Severity entity (with individual instances of "Crasher", "Minor", etc) that are referenced by all bugs in the system. It is tempting to always create relationship back-references (i.e. Bug=>Severity, Severity=>>Bug). However, be aware that if you create the reference from Severity back to Bug, any time a Bug is added and you properly use the addObjectToBothSidesOfRelationshipWithKey method, EOF will fault in the ENTIRE "bugs" relationship on Severity prior to adding your new bug to the end of the list. The consequences of this can be crippling to your application. As the number of bugs increases, it will take longer and longer to add a new bug. The recommended best practice for this is to only create Bug=>Severity and NOT create the reverse relationship. In the event that you need to perform that fetch, you can manually construct the EOFetchSpecification rather than use the automatic approach.

Note that this is a filed bug against EOF. One approach that EOF could use is to only add the object to Severity's bugs relationship if the bugs relationship has already been faulted into memory. If the array has not yet been faulted, then causing the fault on insert is potentially very expensive. The reasoning for the current behavior is to maintain the ability to access the newly committed Bug via the Severity bugs relationship prior to committing your transaction (i.e. faulting the relationship from the database wouldn't yet return the newly inserted Bug). This is very important to maintaining object graph consistency pre-saveChanges, but does come at a high performance cost.

Disposeing your EOEditingContext
Calling dispose on your EOEditingContext is not strictly required. When the EOEditingContext is no longer referenced, it will be automatically disposed. However, the question is how long it takes the GC to get to your object. If you call dispose manually, you won't hurt anything, and you immediately decrement the snapshot reference counts. If your EC is falling out of scope or you set it to null, then it's probably a tossup as to who gets to it first -- GC finalizing your EC or you manually calling dispose. It is recommended that you dispose your EOEditingContext when you are in a long running process in a single method where the EOEditingContext will not go out-of-scope until the end of the method.

Calling System.gc
Calling System.gc is usually a bad idea and can cause performance problems in your application. Additionally, System.gc is not an order, it is a request, so if your application is relying on this command to execute, you should re-evaluate your application's design, because you may run into problems with this.

Anecdotes on editingContext.invalidateAllObjects
It can be tempting to resolve memory problems by calling editingContext.invalidateObject(..) or editingContext.invalidateAllObjects. Avoid this. You will only hurt yourself in the long run. Invalidating is very aggressive and WILL cause exceptions to be thrown if someone in another EOEditingContext is modifying an EO that you invalidate in your EOEditingContext (the shared snapshots will be destroyed, resulting in an exception on .saveChanges in the other context). It should only be used under very controlled situations where you understand the implications of the method.

Chuck Hill
As for invalidating objects, this is something to be avoided. I admit that I have been driven to desperation a couple of times and used this, but only with regrets and reservations.

Art Isbell
I just have a bias against using invalidateAllObjects because, for me, it's caused more problems than it's solved.

Mike Schrag
The couple of times I resorted to this, I regretted it later, because it ended up screwing me. The biggest thing is you toss snapshots that people might be in the middle of editing, and that's going to cause really funky problems. It's a really heavy-handed way to go.

NSUndoManager
One of the most common memory problems people run into with WebObjects is the NSUndoManager. WebObjects has a particularly cool feature in that it supports an undo stack for EO transactions. Each time you saveChanges, you push an undoable set of changes onto the stack. The downside of this behavior is that you end up with strong references to old EO states, which can be deadly in a large EOF operation.

There are several fixes for this. One is to simply disable the NSUndoManager on your editing context by calling:

editingContext.setUndoManager(null);

It has been referenced that setting the undo manager to null may cause issues with deletes under certain circumstances. In testing this with WebObjects 5.3, the situation could not be reproduced, but if you use WebObjects 5.2 or lower, you should be aware that you might run into problems.

The recommended alternative in this case is to disable the registration of undo events by calling:

editingContext.undoManager.disableUndoRegistration;

Note that setting the undo levels to 0 using setLevelsOfUndo does not work, as 0 means no limit!

Prior to 5.2, the NSUndoManager had effectively infinite undo levels by default. The javadoc of WO 5.3 still mentions the following:

''EOEditingContext's undo support is arbitrarily deep; you can undo an object repeatedly until you restore it to the state it was in when it was first created or fetched into its editing context. Even after saving, you can undo a change. To support this feature, the NSUndoManager can keep a lot of data in memory.''

However, as of 5.2, if you are using the session defaultEditingContext, WOSession sets the default undo stack size to 10 if there is no default size specified with the WODEFAULTUNDOSTACKLIMIT parameter.

Lastly you can manually clear your NSUndoManager when you are done with an operation by calling:

editingContext.undoManager.removeAllActions;

If you use an NSUndoManager, it is recommended that you call this after performing very large saveChanges that involved large amounts of data.

WebObjects 5.2+
This is a description of the current behavior in 5.3 that one might be able to gather if one were to, say, decompile and review the entire process -- not that i would ever do this or condone it, of course -- but if you DID, you would probably gather exactly this info, which is pretty well documented (and seems to behave to-spec) in the 5.2 release notes:

As of 5.2, the way it works is: The snapshots in EODatabase have a reference count. Each editing context that fetches an EO increments the reference count. The EC holds onto that EO via a WeakReference. When the WeakReference is reclaimed, the snapshot reference count can decrease (note CAN, not IMMEDIATELY WILL -- the editing context keeps reference queue which is only processed periodically). When the count gets to zero, the database forgets the snapshot. If you have entity caching enabled, then EODatabase ignore reference count (or keeps it at "1" as a minimum) and it will not go away in a read-only scenario. If you modify any entity of that type and saveChanges in your EditingContext, a cached entity's cache will be entirely flushed. (NB: Keep this in mind, because if you are caching a large amount of data that is writable, it will NOT be very smart about updating that cache -- It's blown away with every update and then it immediately reloads the entire set of objects for that entity at the next access)

If you have retainsAllRegisteredObjects enabled on your editing context, it will NOT use WeakReferences. Under this circumstance, the EO reference count is only decreased when 1) you dispose the editingcontext or 2) you forget or invalidate the object.

When you modify an object in an editing context, the editingcontext keeps a strong reference to the objects until you saveChanges (or revert, reset, etc), at which point the strong references are cleared and the only remaining reference is the weakreference like before.

If you have an undo manager enabled, it will keep a strong reference to the affected EO's as long as the undo is around.

I do wonder if EC's should be using SoftReferences instead of WeakReferences ... Would seem to be more friendly to the users of those EO's.

If you are using WO pre 5.2, then none of the WeakReference stuff applies, and everything is purely done with snapshot reference counting -- it should behave like retainsAllRegisteredObjects = true in 5.2.

WebObjects Pre 5.2
Prior to 5.2, all snapshots were simply reference counted by EOEditingContext. If an EO was faulted into your EOEditingContext, it would not go away until the EOEditingContext itself was disposed. As a result, if you have an application deployed on a pre-5.2 WebObjects, you will need to adopt a strategy of periodically disposing your EOEditingContext and creating a new one.

Chuck Hill
In our experience, EOF is not too good at bulk operations like this. If we have a lot to do, and don't need logic from the EO, we wander down to the EOAccess level, and whip up some batch insert statements. You might even want to consider straight JDBC.

OK that said,
 * save periodically
 * don't retain references to objects you have inserted
 * if that does not work, try creating a new EC periodically
 * a bit heavy handed, but ec.invalidateAllObjects should dump out all the snapshots as well.

A couple of useful comments: http://lists.apple.com/archives/webobjects-dev/2004/Sep/msg00225.html http://lists.apple.com/archives/webobjects-dev/2004/Sep/msg00228.html

It is always interesting to read the EOF docs, the JavaDocs are for API only while the EOF docs contain much valuable information. http://developer.apple.com/documentation/WebObjects/Enterprise_Objects/index.html

"EOEditingContexts use weak references to the EOEnterpriseObjects registered with them. ... EOEditingContexts hold all inserted, deleted, or updated objects by strong references. These strong references are cleared by the EOEditingContext methods saveChanges ..." -- http://developer.apple.com/documentation/WebObjects/Enterprise_Objects/Managing/chapter_7_section_9.html

Alan Ward
Re: creating a new EC periodically I'd jump straight to this option (based on my experience). I have done a couple of similar tasks and found that the best way to ensure that your app doesn't balloon up is to periodically ditch the EC and create a new one. Seems like it shouldn't be necessary.... but it works.

Ken Anderson
My guess is the memory increase is due to snapshots, which, as I understand it, will never go away, and wouldn't be considered a bug (to me anyway).

For dealing with a forever-import problem I had, where I didn't want the strong handed 'new EC' plan, I wrote this method, which keeps the snapshots down:

public static void forgetObjectsAndKeypaths(EOEditingContext ec, NSArray eos, NSArray keypaths) { Enumeration eoEnum = eos.objectEnumerator; while (eoEnum.hasMoreElements) { EOGenericRecord eo = (EOGenericRecord) eoEnum.nextElement; Enumeration keypathEnum = keypaths.objectEnumerator; while (keypathEnum.hasMoreElements) { String keypath = (String) keypathEnum.nextElement; EOFaulting faulting = (EOFaulting) eo.valueForKeyPath(keypath); if (faulting != null && !faulting.isFault) { if (eo.isToManyKey(keypath)) { NSArray relEos = (NSArray) eo.valueForKeyPath(keypath); EOHelper.forgetObjects(ec, relEos); } else { ec.forgetObject((EOCustomObject) eo.valueForKeyPath(keypath)); }       }      }      ec.forgetObject(eo); } }

You can use it like this:

EOHelper.forgetObjectsAndKeypaths(ec, arrayOfEOsToForget, new NSArray(new String[]{"rel1", "rel2"});

Of course, all the EOs in the array need to be the same entity for keypaths to work!


text:
WebObjects/Web Applications/Deployment/Memory Settings

Paul Lynch
If you set it per instance using JavaMonitor, it goes in Instance Settings, Additional Arguments, with all the other command line arguments.

In the project (Xcode 2.2), inspect the Executable for your app, and use the Arguments tab. Like the example Jacky Gagnon used:

-Xms64m -Xmx300m

Robert Walker
There is one additional option that can be used to ensure/override the memory setting for all instances (even if they are not included in the arguments in JavaMonitor).

On the aggregate target there is a JVM_OPTIONS key in Expert View. Entering the memory settings here will include them in the launch arguments of every instance.

Example: java -XX:NewSize=2m -Xmx64m -Xms32m -DWORootDirectory="/System" -DWOLocalRootDirectory="" -DWOUserDirectory="/Users/robertwalker/Source/MyWOApp/build" -DWOEnvClassPath="" -DWOApplicationClass=Application -DWOPlatform=MacOS -Dcom.webobjects.pid=4128 -Xmx256m -classpath WOBootstrap.jar com.webobjects._bootstrap.WOBootstrap -WOPort 55555


text:
Programming for Palm OS/SuperWaba

Download the SuperWaba SDK
You can download it from here: http://www.superwaba.com.br/en/downloads.asp *404 error

If it requires you to log in, either create an account (free) or use an account from BugMeNot.com.

Unpacking the SDK
If you're running Linux, you can rename the .exe to .rar and use unrar to unpack the SDK. unrar x GPL_SuperWabaSDK.rar

Setting Up Eclipse
Create a new Java Project in Eclipse "from existing source", with the directory: $SUPERWABA/src/java/

Add an External Archive to the Build Path: $SUPERWABA/lib/SuperWaba.jar.

After some fiddling, my .classpath ended up like this:

Running the Samples
Run:Run... Java Application
 * Main class: waba.applet.Applet
 * Arguments: superwaba.samples.ui.gadgets.UIGadgets

Our First Program
package superwaba.samples.helloworld;

import waba.ui.Label; import waba.ui.MainWindow;

public class HelloWorld extends MainWindow { public HelloWorld { super("HelloWorld!", TAB_ONLY_BORDER); }	@Override public void onStart { add(new Label("My Hello World Program"), CENTER, CENTER); } }

Run this program the same way you would one of the sample applications.

title: Programming for Palm OS/SuperWaba


text:
WebObjects/Web Applications/Deployment/Scheduled Restart

Chuck Hill
Let's take a look at what happens in a little more depth. When the appointed time comes, wotaskd sends the application a message to start refusing new sessions. The application will start redirecting all subsequent requests without a session to an instance that is not refusing new sessions. Of course, in your case eventually all are refusing and the woadaptor throws up its hands in dismay and declares "No Instance Available".

But the part of interest to us happens before that. After being told to refuse new sessions, the app quietly works away serving the users who already had sessions, waiting for them to terminate. As each terminates it checks to see if the number of remaining sessions is below the threshold (1 by default). If so it calls terminate and shuts down the run loop. At this point, if all is well, there are only daemon threads running and the JVM stops them and exits. wotaskd notices that the app is not running and restarts it. That is if all is well.

Now, what can go wrong? The two most common problems that I have seen are (1) immortal sessions - the session count never drops to zero and (2) stuck threads that are not daemon threads. The first situation prevents the app from calling terminate and beginning the exit process. The second situation prevents the JVM from terminating after the main app threads stop.

Immortal sessions are caused by an exception being raised from your code that prevents the session from being checked into the session store. The number one cause of this is exceptions being raised in the sleep method of session. If you use this method, wrap it in a try...catch for throwable. Do not let this method throw under any circumstances. Immortal sessions can also be caused by exceptions being thrown from awake and terminate and I have no doubt there are other ways as well.

Stuck threads usually result from some sort of thread deadlock and can often result from immortal sessions when a request is made for a session that was never checked in from another thread. A similar situation can occur if your are creating threads in your application that are not marked as daemon threads and not shut down when the application terminates.

OK, all that is well and good but what do you do about this? The first thing you want is to wait for this to happen and get a thread dump of the application. There are some instructions here: http://lists.apple.com/archives/webobjects-dev/2003/Sep/msg00362.html Note that the file you need to edit is in /System/Library/WebObjects/JavaApplications/wotaskd.woa/Contents/Resources. Make sure that the appserver user has write permissions on the directory/file you point it to.

The next thing you want to do is to add some better logging to your application. At a minimum, I would suggest:
 * Log ID when session is created
 * Log ID when session's terminate is called.
 * Log the application's remaining activeSessionsCount when session's terminate is called
 * Log start and stop of RR look in dispatchRequest in application
 * Log when session are refused and activeSessionsCount in refuseNewSessions(boolean)
 * Log when application's terminate is called

Chuck Hill
My first choice would be to fix your code. Second, it you have a long session time out and users are still working, then it could take quite a while for the app to restart (as long as the users keep working plus the session timeout). Third, if the JVM is waiting on a stuck thread there is not much you can do as any daemon thread to send the text page would have been killed already (hmmm, I think so at least). OK, so ignoring all that, start a timer as a daemon thread in refuseNewSessions(boolean) when true is passed. When the timer fires, send the text message. Or, if you like to sleep as much as I do, just call System.runtime.exit(1). If refuseNewSessions(boolean) is later called with false, kill the timer. That is just in case someone is clicking around in JavaMonitor.


text:
WebObjects/Web Applications/Deployment/Additional Monitoring

Chuck Hill
We usually just use a script that runs as a cron job. It hits a direct action on the app that returns a known "all is OK" response. If that does not get returned, alarms ring.


text:
WebObjects/EOF/Using EOF/Custom Qualifiers

Chuck Hill
Pierre Bernard has some very cool qualifier extensions on his site: http://web.archive.org/20050215013412/homepage.mac.com/i_love_my/code.html

You might find what you need there or at least a good starting point.

Pierre Bernard
The qualifiers referenced by Chuck have been folded into the Houdah WebObjects Frameworks project. More information can be found in the Wiki:

http://code.google.com/p/houdah-webobjects-frameworks/wiki/QualifierAdditions


text:
WebObjects/EOF/Using EOF/Custom EOAdaptor

It's surprisingly easy to create a simple custom EOAdaptor. In 2002, there was a post to the Omni WebObjects mailing list with the code necessary to do implement a File System EOAdaptor (obviously the WO version is a little old, but it should be a good starting point):

http://www.wodeveloper.com/omniLists/eof/2002/June/msg00053.html


text:
WebObjects/EOF/Using EOF/Schema Changes

Christian Pekeler
James Seigel and I have written an article that might be of interest to this group. We describe a simple method for encoding structural changes to a database as objects. These objects can be used by applications to automatically bring their databases up-to-date on startup. We include example source code for WebObjects, usage patterns, and the lessons we have learned. Check it out:

http://www.stepwise.com/Articles/2005/DBChanges

title: WebObjects/EOF/Using EOF/Schema Changes


text:
WebObjects/Web Applications/Development/Tips and Tricks

URL's

 * wocontext.request.uri = the URL currently being requested

There are several different URL's associated with your application, all of which can be retrieved from various methods on WOApplication. Here is a quick cheat sheet of them:
 * WOApplication.application.baseURL = /WebObjects
 * WOApplication.application.applicationBaseURL = /WebObjects
 * WOApplication.application.cgiAdaptorURL = http://hostname/cgi-bin/WebObjects
 * WOApplication.application.directConnectURL = http://hostname:port/cgi-bin/WebObjects/MyApplication.woa
 * WOApplication.application.frameworksBaseURL = /WebObjects/Frameworks
 * WOApplication.application.servletConnectURL = http://hostname/cgi-bin/WebObjects/MyApplication.woa
 * WOApplication.application.webserverConnectURL = http://hostname/cgi-bin/WebObjects/MyApplication.woa/-port

Browser IP
/** Returns the IP address of the client. * This should return accurate information whether in direct connect or webserver deployment mode. * If performance caching is turned on on OS X server, this method will correctly use pc-remote-addr * @return The IP address as a string. */   public static String clientIP(WORequest request) { Object ipAddress = request.headerForKey("pc-remote-addr"); if (ipAddress == null) { ipAddress = request.headerForKey("remote_addr"); if( ipAddress == null ) { ipAddress = request.headerForKey("remote_host"); if( ipAddress == null ) { ipAddress = request._remoteAddress; if( ipAddress == null ) { ipAddress = request._originatingAddress; if( ipAddress != null ) ipAddress = ((InetAddress)ipAddress).getHostAddress; }                   }                }        }        return ipAddress == null ? " " : ipAddress.toString; }

NSArray
It's in the docs, but NSArray's implementation of KeyValueCoding is not really what I was expecting. To get an object at a specific numeric index of an NSArray, you'd use the

objectAtIndex

method. So what does

NSArray.valueForKey(String key)

return?

Well, first read the docs: file:///OSX/Developer/Documentation/WebObjects/Reference/com/webobjects/foundation/NSArray.html#valueForKey(java.lang.String)

It turns out that calling valueForKey on an array is the same as calling valueForKey for each element of that array. So if you have an NSArray of Users, calling valueForKey("email"); will return an NSArray of email addresses. calling valueForKey("documents"); will return an NSArray of NSArrays containing document objects. In hindsight (and from looking at the way WOBuilder handles key paths for arrays) this is kind of obvious. But I think the real lesson here is that it is easy to ignore the docs towards the end of an alphabetical page...

HTML-friendly String Truncating
import org.apache.commons.lang.*; //From Apache import org.clapper.util.text.*; // From http://www.clapper.org/ public static String stripHTMLTagsAndConcatenate(String htmlString, int numberOfChar) { return (StringUtils.substringBeforeLast(StringUtils.abbreviate((HTMLUtil.stripHTMLTags(htmlString)), numberOfChar), " ")) + "..."; }