Saturday, January 29, 2005

More on flux

One of the cool things I really like about WindowMaker was the built-in GUI configuration editor. It's really nice to have a GUI to handle configurations because that way you (usually) don't have to worry about a hosed up config file due to some extraneous character that you have no idea how it got in there...

So, enter fluxconf. While this isn't as built-in as the configuration editor in WM, this is WAY better than nothing. There are three programs emerged: fluxconf, fluxkeys, fluxmenu. These are great for quick config changes without hopping into the terminal.

Back to fluxbox

Decided to switch back to fluxbox after getting sick of XFCE4.2, hated the startup time and some other things about it were driving me nuts (winds of change blowing strong today). So, in order to get flux working I wanted a nice volume control and simple calendar: emerge wmmixer wmclock. I'm running "wmclock -exe xcalendar" for instant an calendar on-click. Also, wmmixer is so much nicer than the volume app in XFCE, it's faster, smaller, and more elegent (IMO). Also supports scroll wheel action.

3ddesktop is a cool emerge for some quick eyecandy.

Ruby, Chapter 1

These are notes I've taken while reading Programming Ruby:
Everything in Ruby is an object, no primitives.
No type definitions.
"puts" sends to standard out with new line
"print" or "printf" also used
"gets" assigns user input to (global var) $_


puts "Hello World"


Does not require semicolon delimitation, unless multiple statements on one line

def hoser
puts "Hello hoser"
end

Equivalent to

def hoser; puts "Hello hoser";end;


Ruby constructors executed as follows:

String.new("new string")

or

String.new()


Ruby returns the last expression evaluated in method (thus return statement is not necessary)
Method example:

def errMsg(msg)
result = "Error is #{msg}"
return result
end

OR

def errMsg(msg)
"Error is #{msg}"
end

Programming Ruby, The Pragmatic Programmers Guide states,"Ruby uses a convention to help it distinguish the usage of a name: the first characters of a name indicate how the name is used. Local variables, method parameters, and method names should all start with a lowercase letter or with an underscore. Global variables are prefixed with a dollar sign ($), while instance variables begin with an ``at'' sign (@). Class variables start with two ``at'' signs (@@). Finally, class names, module names, and constants should start with an uppercase letter. "

Arrays grow as needed, can contain object of different types:

arry = [ 9, 'hoser', 2.33 ]

you can dump the array contents with

arry

create an array like

arr1 = []
arr2 = Array.new
arr3 = %w{ stuff1 stuff2 stuff3 stuff4 hoser }

Hashes are similar to arrays but use braces, literal requires two objects for each entry (key value pair):

hoserMap = {
'hoser1' => 'bob',
'hoser2' => 'doug',
'hoser3' => 'hosehead',
'hoser4' => 'Jeremy'
}
puts "this is hoser1 #{hoserMap['hoser1']}"

If logic works like:

if isTrue
puts "true"
elsif isOtherTrue
puts "isOtherTrue"
else
puts "false"
end

Or another sneaky way:

puts "show this if true" if isTrue

while num<10
num = num*num
end
#OR
num = num * num while num<10


Code Blocks and Iterators
Pragmatic, "chunks of code that you can associate with method invocations, almost as if they were parameters. This is an incredibly powerful feature. You can use code blocks to implement callbacks (but they're simpler than Java's anonymous inner classes), to pass around chunks of code (but they're more flexible than C's function pointers), and to implement iterators"

Here's their example:

def callBlock
yield
yield
end

callBlock { puts "In the block" }

produces:

In the block
In the block

You can use blocks to implement iterators, by passing parameters between vertical bars (|):

arry = %w( wheat rice oats barley)
arry.each { |grain| puts grain}

outputs:

wheat
rice
oats
barley

Check out these looping constructs:

10.times { print "*" }
4.upto(20) {|i| print i}
('f'..'j').each {|char| print char}
#output:
**********4567891011121314151617181920fghij



AVI choppy sound under Gentoo,fixed

For some reason the AVI files from my Canon A85 have been playing with choppy sound. Not quite sure how this has come about because it was working perfect the first few tests I did a month ago. Maybe it's because the tests were 320x240 and these are 640x480. Either way, Xine/Kaffeine hoses the sound.

Resolution: VLC *correctly* renders the video and sound (though v.0.8.0 I'm using is command line and it'd be nice to have a gui).

Thursday, January 27, 2005

Tomcat 5.0.27-r4

In order to allow normal users to use tomcat5 after it's emerged
chmod a+rx /opt/tomcat5/
chmod a+wrx /etc/tomcat5
chmod a+wrx /opt/tomcat5/webapps

Following that, normal CDOL deploy scripts executed as expected.

Wednesday, January 26, 2005

Ultra simple Ruby on Rails tutorial

Assumptions are mysql is installed along with ruby and rails

In mysql:

createdb TEST;
create table TEST.test (id int key auto_increment, title varchar(10) not null);

Then execute:
rails test
cd test

Now update config/database.yml

Execute:
ruby script/generate model test
ruby script/generate controller test

edit app/controllers/test_controller.rb:

class TestController <>

scaffold :test

end

Edit config/environment.rb:
ActiveRecord::Base.pluralize_table_names = false


Browse to:
http://localhost:3000/test/list

BING, instant CRUD!

Use Firefox or Netscape instead of Epiphany in Gnome

Gnome 2.8.1 r1: gconf-editor, then use the find capability to change
the epiphany command to netscape or firefox.

Tuesday, January 25, 2005

Ruby on Rails, first glance

Below are notes and thoughts as I went through the Rails tutorial at
http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html?page=1 Database was mysql 4.2.3 and all commands were executed from mysql console.

First,
emerge ruby rubygems
gem install rails --remote

(get rid of proxy in .bashrc, or problem)
"rails " creates all of the files for a rail project in directory
has builtin webserver (WEBrick), invoked from "ruby script/server"
starts up on port 3000
some notes and suggestions on rails presented on default page
"Rails tries very hard to minimize the number of decisions you have to make and to eliminate unnecessary work. When you used the rails helper script to create your empty application, it created the entire directory structure for the application (Figure 9). Rails knows where to find things it needs within this structure, so you don't have to tell it. Remember, no configuration files!"
--http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html?page=2
broken on ruby script\generate controller MyTest
ruby: No such file or directory -- script/generate (LoadError)
need to be in the project directory to run script, woops
"* The controllers subdirectory is where Rails looks to find controller classes. A controller handles a web request from the user.
* The views subdirectory holds the display templates to fill in with data from our application, convert to HTML, and return to the user's browser.
* The models subdirectory holds the classes that model and wrap the data stored in our application's database. In most frameworks, this part of the application can grow pretty messy, tedious, verbose, and error-prone. Rails makes it dead simple!
* The helpers subdirectory holds any helper classes used to assist the model, view, and controller classes. This helps to keep the the model, view, and controller code small, focused, and uncluttered."--http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html?page=2

create the tutorial db with:
create database cookbook

add the sysid(PK, autoincrement):
create table cookbook.recipes (sysid int AUTO_INCREMENT key);

add the other columns:
alter table cookbook.recipes add(title varchar(256) not null,instructions text)
Model for this table is generated by: "ruby script\generate model Recipes"
Controller: "ruby script/generate controller Recipes":
adding "scaffold :recipes" will enable CRUD operations...need more information as to what this is doing. Creating an object that reflects the table?
http://127.0.0.1:3000/recipes/new brings up a generated form to enter all the data corresponding to the fields in the table. Pretty slick.
http://127.0.0.1:3000/recipes/list shows the available records and the ability to Show Edit Destroy. Very slick, this was cake to get up and running and could be very handy for quick db form apps.
Now updating the db table structure:
"alter table cookbook.recipes add(description varchar(256), date datetime);"
Hitting the "new" page again immediately reflects new fields and a nifty date picker.
Can override the "list" view/page by creating an .rhtml template in the views directory (list.rhtml)

created a second table, create table categories(sysid int auto_increment key, kind varchar(55));
ruby script/generate controller Category
ruby script/generate model Category
added "scaffolding :category" to category_controller.rb, can now create records at http://127.0.0.1:3000/category/new

If the pk id is "id" then Rails won't generate a form input or display it. Thus, the sysids in the entries above allowed entries. When I dropped the table and retried with "id" then it becomes hidden. AND, the Show,Edit,Destroy now work.

now to add a "category" to a recipe: alter table recipes add(category_id int(6) not null);
update recipes.rb adding:
belongs_to :category
and category.rb:
has_many :recipes
By adding the above lines code is generated to navigate these relationships. Question is, can Ruby identify db-constrained relationships and do the same thing?

added recipes_controller.rb:
def edit
@recipes=Recipe.find(@params["sysid"])
@categories=Category.find_all
end
then created edit.rhtml in the app/recipes/view directory

need to recreate recipes table with correct id instead of sysid:
create table recipes(id int auto_increment key,title text,instructions text, description text, date date,category_id int(6));

Followed the rest of the tutorial and results were similar (though I changed a couple of column names and edited the code as I progressed).

So, Rails looks to be quite a promising way to generate quick webpages around an existing data model. I'm going to design a database for keeping track of my books and see how quickly I can use Rails to get it churned out into a web app.

Monday, January 24, 2005

Java 1.4.05 emerge

can't install the bin file, some weird checksum issue and _06 we've
had some quirky security issues with .06. So, in order to install
1.4.2.05, download the bin and place it in /usr/portage/distfiles
then:
emerge =sun-jdk-1.4.2.05

XNC #2

Looks like XNC has a manual MIME mapping, that is, you provide an
extension and executable in xnc.ext. While it is slightly archaic, at
least it works compared to some of the mime-shared-info problems I've
had with Rox.

XNC

Think I may have found the ultimate (for me) file manager: XNC. What's
so cool about it? It's simple, fast, and intuitive. I've toyed with it
for about 10 minutes and I'm liking it much better than Rox. Time will
tell whether it's really as great as I'm speculating...

Friday, January 21, 2005

Tapestry persistence test code

--Begin snippet for Tester.java--


/*
* Created on Jan 21, 2005 by BCS and RCR
*
*/


import org.apache.tapestry.html.BasePage;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.form.IPropertySelectionModel;
import org.apache.tapestry.form.StringPropertySelectionModel;

public abstract class Tester extends BasePage {

private IPropertySelectionModel DROP_DOWN2_MODEL =
new StringPropertySelectionModel(new String[] { "1","2" });

public abstract void setHiddenBoolean(Boolean newVal);
public abstract void setCounter(Integer newVal);
public abstract Integer getCounter();


public void doSubmit(IRequestCycle cycle){
Integer temp = getCounter();
int newInt =0;
if(temp!=null){
newInt = temp.intValue()+1;
}
setCounter(new Integer(newInt));
if (getCounter().intValue()==5){
setHiddenBoolean(Boolean.valueOf("true"));
}
}

public void doCancel(IRequestCycle cycle){
cycle.discardPage(getPage().getPageName());
cycle.activate("Home");
}

public void detach(){
super.detach();
}

/**
* @return Returns the DROP_DOWN2_MODEL.
*/
public IPropertySelectionModel getDROP_DOWN2_MODEL() {
return DROP_DOWN2_MODEL;
}
/**
* @param drop_down2_model The DROP_DOWN2_MODEL to set.
*/
public void setDROP_DOWN2_MODEL(IPropertySelectionModel drop_down2_model) {
DROP_DOWN2_MODEL = drop_down2_model;
}
}



--End Tester.java snippet--
--Begin Test.page snippet--



<!-- generated by Spindle, http://spindle.sourceforge.net -->

<page-specification class="Tester">

<description>add a description</description>
<property-specification name="dd1" type="java.lang.Integer" persistent="yes"></property-specification>
<property-specification name="dd2" type="java.lang.String" persistent="yes"></property-specification>
<property-specification name="dd3" type="java.lang.Character" persistent="yes"></property-specification>
<property-specification name="input1" type="java.lang.String" persistent="yes"></property-specification>
<property-specification name="hiddenBoolean" type="java.lang.Boolean" persistent="yes" value="false"></property-specification>
<property-specification name="counter" type="java.lang.Integer" persistent="yes"></property-specification>
</page-specification>

--End Test.page snippet--
--Begin Test.html snippet--

<span jwcid="@Shell" title="test this">
<span jwcid="@Body">
<span jwcid="@Form">
<span jwcid="@PropertySelection" model="ognl:DROP_DOWN2_MODEL" required="true" submitonchange="false" value="ognl:dd2"/>
<span jwcid="@Hidden" name="hiddenVal" value="ognl:hiddenBoolean"/>
<span jwcid="@TextField" name="inp" value="ognl:input1"/>
<span jwcid="@Insert" value="ognl:counter"/>
here is the hidden value: <span jwcid="@Insert" value="ognl:hiddenBoolean"/>
<span jwcid="@LinkSubmit" listener="ognl:listeners.doSubmit">submit</span>
<span jwcid="@LinkSubmit" listener="ognl:listeners.doCancel">cancel</span>
</span>
</span>
</span>

--End Test.html snippet--

Persistent properties in Tapestry

Learned a couple things this week in Tapestry, one of which will require quite a bit of refactoring.

First, the LinkSubmit will solve many problems in the UI that the client requires. Up to this point we were planning on writing custom JavaScript to facilitate submitting a form from a hyperlink.

Secondly, I've misunderstood the Tapestry In Action book and have coded a couple pages wrong--which has been the cause of frustration and irritation in some of the behavior. My foul-up has been that I've coded all of the page properties as instance variables. My interpretation of the material in the book was wrong--I has presumed that page properties could be handled through Tapestry Page specification entries (.page file) or as members of the Page's class. Same presumption for Tapestry's handling of the variable.

Bad presumption.

Tapestry handles the two QUITE differently. In order for the client state to be preserved (between clients) Tapestry must *own* the property. That is, it must be declared in the .page specification and also be (to my experience thus far) an abstract value. This way, Tapestry manage the properties' persistence rather in the extended class that Tapestry manages. Otherwise, when the page is available in the pool, everyone shares the instance variables. That's where we began to notice strange things.

Next thing to figure out is initialization necessities (some properties will need to be initialized to different values according to some set of logic) and detachment (resetting the properties).

Overall, I think the refactoring will make the pages a bit more intuitive at first glance. And, it'll save space in the code where we (by necessity) need to define abstract methods purely for the use of other in-class routines. Thus making the page class abstract for Tapestry to manage the persistent properties *and * keeping our code to a minimum. Slick setup. Despite the learning curve and twisting my mind around the concept, kudos to the Tapestry team for developing such an efficient model.

Some links of clarification on the matter:

Wednesday, January 19, 2005

Java and Firefox

http://www.mozilla.org/support/firefox/faq#q2.2
Since I had blackdown jdk,
~/.mozilla/plugins/
ln -s /opt/blackdown-jdk-1.4.2_rc1/jre/plugin/i386/mozilla/libjavaplugin_oji.so

Saturday, January 15, 2005

Canon a85

Emerged gphoto2 and gtkam, plugged in the camera, and perused the
pictures. Very nice, very easy.

Just emerged Stellarium (http://stellarium.free.fr). Incredible! I
think when the kids get a bit older this will come in more handy. For
now it's just cool to see what it'll be like tonight and watch the
skies on my 20" screen. Excellent work, Stellarium team!

Thursday, January 13, 2005

Oracle Gentoo memory sharing

http://gentoo-wiki.com/HOWTO_Install_Oracle_10g#Setting_Limits_for_the_Maximum_Number_of_Open_File_Descriptors_for_the_Oracle_User

you have to add
echo 250 32000 100 128 > /proc/sys/kernel/sem
echo 2147483648 > /proc/sys/kernel/shmmax
echo 4096 > /proc/sys/kernel/shmmni
to /etc/sysctl.conf