Declarative Authorization, Ruby 1.8.7, and Heroku Bamboo
August 31st, 2010
The latest declarative_authorization uses requires the use Ruby 1.8.7 and is incompatible with the Heroku Aspen stack, therefore if you are on the Aspen stack, you must migrate to the Bamboo stack that has Ruby 1.8.7.
After you have migrated to the Bamboo stack, you will find that your Heroku app will not start, this is because incompatible gems have been pulled in, which conflict with Rack 1.1.0, when Heroku adds the declarative_authorization gem.
To prevent pulling in the incompatible gems, specify in the .gems file:
declarative_authorization --ignore-dependencies
For more details: http://docs.heroku.com/rails236
Git 1.6.6 and Xcode 3.2.x
July 12th, 2010
I like to use git as my primary source code version control. Git commands are simple to use and git’s method of branching, commits, tags are easy to understand and use. However, Xcode supports only svn within the IDE. Git can still be used with Xcode but a .gitignore file and .gitattributes file should be created.
The .gitignore File
In Xcode 3.2.x the *.xcodeproj folder contains project files specific to Xcode. I usually specify to git that the xcodeproj folder should be ignored, except for the pbxproj file within the folder.
# # .gitignore file # # Ignore any build files and older project files build/* *.mode1v3 *.mode2v3 *.pbxuser *.perspective *.perspectivev3 # Don't ignore the pbxproj within the xcodeproj folder !*.xcodeproj/project.pbxproj # Ignore .svn information .svn # Ignore OSX-specific files .DS_Store profile
The .gitattributes File
I usually specify to git that it should not convert, diff, or merge the *.pbxproj file.
# # # .gitattributes file # # Effectively treat the pbxproj as binary # *.pbxproj -crlf -diff -merge
Links
For more info about gitignore
For more info about gitattributes
Talkd and Debian Lenny 5.0.4
June 24th, 2010
When working with other developers, I like to chat on the server itself using talkd. Talkd is the server that notifies a user that someone else wants to initiate a conversation. It acts a repository of invitations, responding to requests by clients wishing to rendezvous to hold a conversation
apt-get install inetutils-inetd apt-get install talk apt-get install talkd
vi /etc/inetd.conf
Make sure you have in the /etc/inetd.conf the following:
talk dgram udp4 wait root /usr/sbin/in.talkd in.talkd ntalk dgram udp4 wait root /usr/sbin/in.ntalkd in.ntalkd
/etc/init.d/inetutils-inetd restart
How to fix the Gulf Oil Spill
June 9th, 2010
Three steps
1) The US government authorizes the release of gold from Fort Knox, via National Security or Executive Order
2) Chop it up into fine powder and mix the powdered gold with biodegradable material, so that it floats and will stick to the oil.
3) Seed the oil slicks with about 1 ounce per cubic foot of oil, on average.
RESULT: You’ll have lots of companies out there sucking the oil up, getting the gold and reselling the oil. you’ll have a gold rush on the beaches. You’ll have people out there getting the oil off the beach (to get the gold).
You’ll generate a short term micro-economy in the Gulf area, as support services are needed to support the gold rushers (hotels, restaurants, food, and equipment!).
Why not? The gold in Fort Knox does nothing, as is. It just sits there. About 4600 tons of gold is available. http://en.wikipedia.org/wiki/United_States_Bullion_Depository
Digital Magazines as a new Market Product
March 22nd, 2010
The Digital Magazine previews, especially VIV Magazine, at http://vimeo.com/10204353 are extremely impressive.
From what I can see, Digital Magazines have both the interactivity of a website with high quality video that enhances the text, graphical content in a way that the normal web-browser is not currently capable.
This brings up some interesting questions:
- Are Digital Magazines the new Web 3.0; where the Digital Magazine on a iPad or tablet becomes a truly immersive experience, compared to a standard web-site. ?
- How will web design and web designers adapt to Digital Magazines on the iPad?
- Should these Digital Magazines be ignored? Are they a fad?
- Will Digital Magazines be the new “web” for the iPad or tablets?
According to City of Orlando’s Creative Village booklet, “Orlando is one of the top 12 digital media clusters in the country. A recent study by the research firm Catalytix validates that Orlando is poised to become a top destination for creative types. According to the study, there are 317 local film and entertainment technology businesses in the area that employ more than 8,000 workers, host $1.4 billion in annual sales and pay $280 million in salaries. Another 822 “arts” businesses employ 6,000 people.The average wage for Orlando’s high- tech worker is $70,000.” (Film & Entertainment Technology: Opportunities and Obstacles for Sustainable Regional Growth, Catalytix; Study Commissioned by The Metro Orlando Economic Development Commission; delivered October 11, 2006.)
It seem from the above Study that Orlando has the creative people, we have the local film and entertainment technology businesses.
Can Orlando become the premiere production-center for Digital Magazines, here in Florida?
If not, why not?!
Is Orlando doomed to wait for Los Angeles and New York to take the lead? ;
Time Capsule + iPad
March 18th, 2010
If Apple were to update the Time Capsule to become an external database storage hub for the iPad, it would create a huge ecosystem. This new ecosystem would be based upon the Time Capsule having an API that would be accessible from the iPad OS.
Such an combination of products, would open iPad developers to sell turnkey based client/server applications that use multiple iPads talking to a central Time Capsule device. This means for Apple, that it could sell combinations of iPads and Time Capsules.
This may be attractive for small/mid-size businesses where having multiple iPads talking to a central database server is an improvement over their paper-based (and sneaker-net or word-of-mouth) system. The TCO would be relatively low, given the turnkey nature of the iPad and Time Capsule.
Some example costs:
Time Capsule: $300
Four iPads: $2000
Setup Time: 1 hour
Software per iPad: $1-$100, depending on functionality in the Application and App Store competition
Training: None -1 hour, depending on if the User already has an iPhone.
The cost of software per iPad is interesting, since the long-tail effect would almost guarantee that the price will approach $1.
iPad is more functional than an iPod Touch
March 9th, 2010
I reviewed the software development kit APIs for the new iPad. The new APIs have a lot more functionality than what is available with the iPhone SDK. Anyone considering the iPad as being ‘an oversized iPod Touch is only considering the physical form factor, most likely they have not yet reviewed the iPad native SDK.
I think, given the new APIs, the native apps for the iPad will be a new class in itself (targeting the full multi-touch metaphor). I would conjecture that, in the near future, application developers will target the iPad as their primary platform and begin to consider iPhone apps as their apps’s mobile version, with limited functionality and limited screen space.
More articles to come, covering iPhone and iPad development.
Daimoku Update: Agent Smith online!
February 27th, 2010
System Agent AI “Agent Smith” is now online!
In case you didn’t know, the Agents are there to keep order and prevent the Players from becoming ‘Neo’ and hacking the game world, from inside. NPC System Agents will patrol the system looking for anomalies and punish those that attempt to overthrow or hack the game world.
Daimoku Multi-Programmer Online is an environment written in Ruby and ActiveRecord and implemented using Why’s Freaky-Freaky Sandbox. Daimoku allows multiple Ruby programmers to chat, share code and objects in real-time in an EW-Two-style environment.
Visit http://daimoku.elitefrontier.org for more information
Courier IMAP on Debian Lenny with Apple mail.app
February 18th, 2010
If you maintain various virtual domains on a Debian Lenny box you can use Apple’s mail.app to access each virtual domain so you can send/receive e-mail as different users on those virtual domains. I use mail.app to access many virtual domains, on a daily basis and it works pretty well. This short article, describes how to set up the server correctly.
Install Courier with IMAP and IMAP SSL. If you want to be somewhat secure, only install the courier-imap-ssl. When you are prompted if you want to set up the web configuration directories, select NO.
apt-get install courier-imap courier-imap-ssl
If you are running mailx, you’ll need to install the mailbox conversion program
apt-get install mb2md
Create the Courier mail directory, using maildirmake
su - myuser cd /home/myuser maildirmake Maildir
Convert the contents of the current mbox to the Maildir
su - myuser mb2md -s /home/myuser/mbox -d /home/myuser/Maildir
For future incoming e-mail, let the email go into mbox, but put a copy into Maildir, create a .procmailrc with the following:
MAILDIR=$HOME/Maildir :0c $MAILDIR/
Daimoku Multi-Programmer Online: Update
January 31st, 2010
Daimoku Multi-Programmer Online is an environment written in Ruby and ActiveRecord and implemented using Why’s Freaky-Freaky Sandbox. Daimoku allows multiple Ruby programmers to chat, share code and objects in real-time in an EW-Two-style environment.
System Agent AIs
NPC System Agents are now online. The only thing left is to program their AI to look for game world anomalies.
In case you didn’t know, the Agents are there to keep order and prevent the Players from becoming ‘Neo’ and hacking the game world, from inside. NPC System Agents will patrol the system looking for anomalies and punish those that attempt to overthrow or hack the game world.
Alpha Testers Wanted
If you’re interested in being an alpha tester and messing around with the system, send an e-mail to [rdegraci @ gmail com] with the subject “Request Daimoku Alpha Test”.
Any questions? Just ask in the comments.
Snow Leopard Locale and Postgresql
January 8th, 2010
The default clean installation of Snow Leopard uses the en_US.us-ascii locale. Unfortunately, when installing postgresql 8.3 using macports, the installer will complain when initializing the database, for example:
sudo su postgres -c '/opt/local/lib/postgresql83/bin/initdb -D /opt/local/var/db/postgresql83/defaultdb'
You will get the following error
The database cluster will be initialized with locale en_US.us-ascii. could not determine encoding for locale "en_US.us-ascii": codeset is "us-ascii" initdb: could not find suitable encoding for locale en_US.us-ascii Rerun initdb with the -E option. Try "initdb --help" for more information.
The solution is to change the locale. First we list the locales available:
Outrun:db rdegraci$ locale -a | grep en_US en_US en_US.ISO8859-1 en_US.ISO8859-15 en_US.US-ASCII en_US.UTF-8
Now we set the locale to en_US.UTF-8
Outrun:~ rdegraci$ export LC_ALL=en_US.UTF-8Now start the server
Outrun:~ rdegraci$ sudo su postgres -c '/opt/local/lib/postgresql83/bin/initdb -D /opt/local/var/db/postgresql83/defaultdb'You should get the following output
The files belonging to this database system will be owned by user "postgres". This user must also own the server process. The database cluster will be initialized with locale en_US.UTF-8. The default database encoding has accordingly been set to UTF8. The default text search configuration will be set to "english". fixing permissions on existing directory /opt/local/var/db/postgresql83/defaultdb ... ok creating subdirectories ... ok selecting default max_connections ... 20 selecting default shared_buffers/max_fsm_pages ... 1600kB/20000 creating configuration files ... ok creating template1 database in /opt/local/var/db/postgresql83/defaultdb/base/1 ... ok initializing pg_authid ... ok initializing dependencies ... ok creating system views ... ok loading system objects' descriptions ... ok creating conversions ... ok creating dictionaries ... ok setting privileges on built-in objects ... ok creating information schema ... ok vacuuming database template1 ... ok copying template1 to template0 ... ok copying template1 to postgres ... ok
Apache 2 Load-balancer and Rails
January 2nd, 2010
A quick and dirty way of setting up Rails and Apache2, is using Apache’s balancer module. You’ll need to enable the proxy module, and the proxy balancer module and then setup the configuration, as follows:
Set up the load balancer, to forward requests to the localhost, port 4040
<proxy balancer://my_site.com>
BalancerMember http://127.0.0.1:4040
Order allow,deny
Allow from all
</proxy>
Configure the virtual host to point to the Rails Application’s root directory, located at /var/www/my_site.com.site/
<VirtualHost *:80>
ServerAdmin hostmaster@my_site.com
ServerName my_site.com
ServerAlias www.my_site.com
DocumentRoot /var/www/my_site.com.site/
ErrorLog /var/log/apache2/error_my_site.com.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/access_my_site.com.log combined
ProxyPass / balancer://my_site.com/
ProxyPassReverse / balancer://my_site.com/
ProxyPreserveHost on
ProxyPass /images !
ProxyPass /stylesheets !
Alias /images /var/www/my_site.com.site/public/images
Alias /stylesheets /var/www/my_site.com.site/public/stylesheets
</VirtualHost>
Start the Rails app to listen on localhost, port 4040. Finally restart the Apache server. If all goes well, the Apache server will forward requests to the Rails app.
From an OS to a Conversation
December 1st, 2009
A deeper view of Google Wave suggests that Google may want to change how people converse (via Google Wave) and thereby build a platform of tools to let people manage how they converse.
The File Metaphor become a Conversation Metaphor and the concept of “OS” becomes “Tools to manage the Conversation.”
Continuing this idea, means…
- File Copy becomes “a tool to copy Conversations”
- File Diff becomes “a tool to diff Conversations”
- File Delete becomes”a tool to delete Waves”
- Folders become “a tool to group Conversations”
- File Search becomes “a tool to search Conversations”
Possible innovation
- Searching across Waves for common ideas and connecting people based upon those connections
- The concept of Peripherals becomes “Devices that can understand Conversations”
An exciting idea
The idea of “Devices that can understand Conversations” is very exciting and that can possibly be the next set of innovations from Google, since they are already in-place with mobile devices.A little bit of this and that
November 30th, 2009
Back in 2002, I started writing C++ with a unique style of combining Modern C++ Design and Domain Driven Design. My endeavor was to write a 3D game engine. It was a fun exercise.
First, define the Math Trait. We will use the Real Number System
template <typename T>
struct RealNumberSystem
{
//3 tuple Reals
static int const N=3;
typedef T Radian;
typedef T Theta;
typedef T Rho;
typedef T Radius;
typedef T Scalar;
};
Next, define the Geometry Trait. We will use Standard Euclidean. The Tuple4 typedef is interesting.
struct StandardEuclidean
{
static int const RightHanded=1;
static int const LeftHanded=0;
typedef Vector1x3<float> RowVector;
typedef Vector3x1<float> ColumnVector;
typedef Matrix3x3<float> Matrix3;
typedef ColumnVector Origin;
typedef ColumnVector Axis;
typedef ColumnVector AnyVector;
typedef ColumnVector ComponentVector;
typedef Matrix3 Basis;
typedef ColumnVector Point;
typedef ColumnVector Normal;
typedef ColumnVector Direction;
//Four dimensions
typedef Vector<float,4,1,Storage2Dim> Tuple4;
};
The following is the most critical class, which I think is the linch-pin that holds the math and the geometry together. Without this class, there is NO mathematical representation of a geometrical point, therefore the domain semantics within the code would eventually break down. I think this is the most conceptually beautiful code I have ever written:
//Mathematical representation of Geometrical Point
#include "Vector.h"
template <typename T>
class Cartesian : public Vector3x1<T>
{
public:
Cartesian(T x, T y, T z) : Vector3x1<T>(x,y,z)
{
}
};
Finally, define the Coordinate Systems and transformations between the systems
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//CoordinateSystem Template Class Declaration
template <typename T,
template <typename T1> class MathTrait=RealNumberSystem,
typename GeometryTrait=StandardEuclidean>
class Cartesian3DCoordinateSystem
{
public:
//Direct Access
typename GeometryTrait::Axis m_U[MathTrait<T>::N];
typename GeometryTrait::Origin m_P;
Cartesian3DCoordinateSystem()
{
if(GeometryTrait::RightHanded)
{
m_P.Set(0,0,0);
m_U[0].Set(1,0,0);
m_U[1].Set(0,1,0);
m_U[2].Set(0,0,1);
}
else
{
m_P.Set(0,0,0);
m_U[0].Set(0,0,1);
m_U[1].Set(0,1,0);
m_U[2].Set(1,0,0);
}
}
//Create this Coordinate System's Basis to match X
Cartesian3DCoordinateSystem(const typename GeometryTrait::AnyVector& X)
{
if(GeometryTrait::RightHanded)
{
m_P.Set(0,0,0);
m_U[0].Set(1,0,0);
m_U[1].Set(0,1,0);
m_U[2].Set(0,0,1);
}
else
{
m_P.Set(0,0,0);
m_U[0].Set(0,0,1);
m_U[1].Set(0,1,0);
m_U[2].Set(1,0,0);
}
typename MathTrait<T>::Scalar Y[MathTrait::N]={0};
for (int i=0; i<MathTrait<T>::N; ++i);
{
Y[i]=VectorColumn3::Dot(m_U[i],(X-m_P));
m_U[i]*=Y[i];
}
}
typename GeometryTrait::Basis GetBasis()
{
typename GeometryTrait::Basis R(m_U[0],m_U[1],m_U[2]);
return R;
}
};
template <typename T,
template <typename> class MathTrait,
typename GeometryTrait>
Vector3x1<T> Cylindrical2Cartesian(const CylindricalCoordinateSystem<T,MathTrait,GeometryTrait>& c)
{
//m_Angle must be in Radians
return (Vector3x1<float>((c.m_R*sin(c.m_Angle)),(c.m_R*cos(c.m_Angle)),0));
}
template <typename T,
template <typename T> class MathTrait=RealNumberSystem,
typename GeometryTrait=StandardEuclidean>
class CylindricalCoordinateSystem
{
public:
//Direct Access
typename GeometryTrait::Origin m_Z;
typename MathTrait<T>::Theta m_Angle;
typename MathTrait<T>::Radius m_R; //Radians
CylindricalCoordinateSystem()
{
m_Angle=T();
m_R=T();
}
void SetAngleDegrees(T angle)
{
const float pi=3.141592653f;
const float radconv=pi/180;
m_Angle=angle*radconv;
}
//The axis parameters are perpendicular
CylindricalCoordinateSystem(T x, T y, typename GeometryTrait::Origin Z)
{
//x and y are relative to Z
x=Z.x-x;
y=Z.y=y;
m_R=sqrt((pow(x,2)+pow(y,2)));
m_Angle=(acos(x/m_R));
if(y<=0) m_Angle=-m_Angle;
}
};
template <typename T,
template <typename T> class MathTrait,
typename GeometryTrait>
Vector3x1<T> Spherical2Cartesian(const SphericalCoordinateSystem<T,MathTrait,GeometryTrait>& c)
{
return (Vector3x1<float>((c.m_R*sin(c.m_PolarAngle)*cos(c.m_Azimuth)),(c.m_R*sin(c.m_PolarAngle)*cos(c.m_Azimuth)),(c.m_R*cos(c.m_PolarAngle))));
}
template <typename T,
template <typename T1> class MathTrait=RealNumberSystem,
typename GeometryTrait=StandardEuclidean>
class SphericalCoordinateSystem
{
public:
//Direct Access
typename MathTrait<T>::Radius m_R;
typename MathTrait<T>::Theta m_Azimuth;
typename MathTrait<T>::Rho m_PolarAngle;
SphericalCoordinateSystem(typename GeometryTrait::Point P)
{
m_R=sqrt((pow(P.x,2)+pow(P.y,2)+pow(P.z,2)));
m_PolarAngle=acos(P.z/m_R);
m_Azimuth=acos(x/(sqrt(pow(P.x,2)+pow(P.y,2))));
}
};
Define a linear component and a plane. I often wonder how things would be different, if we used: typename GeometryTrait = NonEuclidean
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//LinearComponent Template Class Definition
template <typename T,
typename GeometryTrait=StandardEuclidean>
class LinearComponent
{
public:
//Direct access
typename GeometryTrait::Point m_B;
typename GeometryTrait::ColumnVector m_M;
LinearComponent(typename const GeometryTrait::Point& B, typename const GeometryTrait::ColumnVector& M) :
m_B(B), m_M(M)
{
m_M.Normalize();
}
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//Plane Template Class Definition
template <typename T,
typename GeometryTrait=StandardEuclidean>
class Plane
{
public:
//Three dimensional representation
typename GeometryTrait::Point m_P;
typename GeometryTrait::Normal m_N;
//Four dimensional representation
typename GeometryTrait::Tuple4 m_ND; // <N,D>
Plane() : m_P(),m_N()
{
}
Plane(const T& px, const T& py, const T& pz,
const T& nx, const T& ny, const T& nz, const T& d) : m_P(px,py,pz),m_N(nx,ny,nz),m_ND(nx,ny,nz,d)
{
m_N.Normalize();
assert( (Vector<float,3,1>::Dot(m_N,m_P) + (m_ND.m_Storage.M[3][0])==0));
}
Plane(const T& A, const T& B, const T& C, const T& D) : m_N(A,B,C), m_P(), m_ND(A,B,C,D)
{
assert(m_N.Magnitude()>0);
(m_ND.m_Storage.M[3][0])/=m_N.Magnitude();
m_N.Normalize();
//Create a dummy Point
m_P=m_N * -m_ND.m_Storage.M[3][0];
//D==-(N dot P)
T ndotp=(Vector<T,3,1>::Dot(m_N,m_P));
T d=m_ND.m_Storage.M[3][0];
assert(fabs(d + ndotp) < 0.001f);
// N dot P + D == 0
T dd=(Vector<T,3,1>::Dot(m_N,m_P) + (m_ND.m_Storage.M[3][0]));
assert(fabs(dd) < 0.001f); //dd==zero
}
void SetNormal(const T& x, const T& y, const T& z)
{
m_N.Set(x,y,z);
m_N.Normalize();
m_ND.Set(m_N.x,m_N.y,m_N.z,0); //Direction
}
void SetPoint(const T& x, const T& y, const T& z)
{
m_P.Set(x,y,z);
}
void SetD(const T& d)
{
m_ND.m_Storage.M[3][0]=d;
}
T GetD() const
{
return m_ND.m_Storage.M[3][0];
}
Plane(typename const GeometryTrait::Point& P, typename const GeometryTrait::Normal& N) : m_P(P), m_N(N)
{
//Make calculations easier by normalizing
m_N.Normalize();
m_ND.Set(N.x,N.y,N.z,-(Vector<float,3,1>::Dot(m_N,P)));
assert( (Vector<float,3,1>::Dot(m_N,m_P) + (m_ND.m_Storage.M[3][0])==0));
}
};
I’ve left out the Matrix template and Vector template code, since it’s pretty boring.
Hyper-Meta-Protocol
November 18th, 2009
Twitter is an informal protocol for transferring ideas and opinions in extremely compact form. Interestingly, Humans have adapted to the protocol, instead of the protocol adapting to Humans. These User-created protocols ride on top of of Twitter and are adopted by other Twitter users, if found useful.
Meta Protocol?
If we consider this informal protocol for a moment, we start to realize the protocols can be considered a Hyper-Meta-Protocol (HMP) or a protocol that is extensible but can also define itself.Mechanization
So let’s try to mechanize the adoption of meta-protocols that ride on top of a particular protocol:1) A protocol is essentially the process of synchronizing two or more state machines and optionally, transferring information between two or more two state machines.
2) Given the definition of protocol, we can constrain state machine changes such that those changes can be synchronized between the two or more separate state machines and therefore create different state-machines pairs, maintaining different meta-protocol sessions.
3) We reconcile differences or contradictions between different Users of the protocol, by performing squelching of non-popular meta-protocol sessions at the server level..
Some properties
- Stateful
HMPs are stateful, in that an HMP is implemented by a State Machine
- In-Band
HMPs are recursively in-band capable. That is to say, an HMP may contain another in-band HMP.
- In-Band Modification
In-band HMP/State-Machine may inspect/modify the containing HMP, but only if the containing HMP/State-Machine allows.