Thursday, October 26, 2006

iterating an Enumerable just to create another array...

via ActiveSupport (thanks Jamis!):

values.map(&:name)

or the standard way

values.collect{|val| val.name}

Wednesday, October 25, 2006

subversion and gse-locate.el

Updated this chunk in gse-locate.el:

(defvar gse-locate-regexp-list
(list "\\.elc"
"\\.class"
"/CVS"
"/target/classes"
"#"
"~"
".cvsignore"
"/\.svn/"
)
"A list of regular expressions that match \"uninteresting\" filenames.
These will be stripped from the locate list before it is displayed.")

pretty indenting HTML chunks in Emacs

After reading this and installing xmml and psgml, I can now indent a wildly formatted chunk of HTML with indent-region (in sgml-mode) and my buffer is then much more readable and formatted nicely. xmml modifies the faces in sgml-mode for much better readability and color identification.

Tuesday, October 17, 2006

Dependency Inversion conversation with Jamis Buck

This conversation represents the sort of headache/transition in getting out of the strict OO mindset and contract-based programming that Ruby allows you to intuitively avoid:

(14:45:35) russ: if you have a minute, gotta design question for you. I have an authentication component that I'd like to turn into a service so it's interchangeable ala Hivemind. Would you recommend copland for doing that? At this point I only have two implementations of the service, but it makes sense to have more in the future...
(14:45:59) jamisbuck: for ruby, I'd avoid DI implementations as a general rule
(14:46:03) jamisbuck: ruby is flexible enough that you don't need them
(14:46:11) russ: the alternative I could think of would be to create some sort of abstract base class and then extend as needed...though not sure how that would fit into Ruby's methodology
(14:46:32) russ: I'm still stuck in j2ee thinking
(14:46:40) jamisbuck: :) it took me two years to come around :)
(14:46:49) russ: so recommendations for my issue?
(14:47:02) jamisbuck: well, you could use a factory class
(14:47:10) russ: two different classes, rely on some static class and put the logic in there to call the appropriately underlying?
(14:47:11) jamisbuck: Foo.authentication_service
(14:47:18) jamisbuck: sure
(14:47:26) jamisbuck: without knowing all the details that sounds fine
(14:47:30) jamisbuck: there may be an even simpler way to do it
(14:47:39) russ: my problem is contracts: interfaces/abstract base classes
(14:47:52) russ: how to move away from that yet make the Ruby code solid
(14:47:54) jamisbuck: careful not to overthink the problem
(14:48:01) jamisbuck: ruby encourages pragmatic solutions
(14:48:20) jamisbuck: I know that when I was coming out of Javaland, I would frequently overlook the simple solutions because they were so simple :)
(14:48:27) jamisbuck: that's not to say every problem has a simple solution
(14:48:40) russ: indeed
(14:48:49) russ: as usual, your feedback is highly valuable
(14:48:52) russ: thanks Jamis!
(14:48:53) russ: have a good one
(14:48:56) jamisbuck: :) you too!

Thursday, October 12, 2006

middle-click selected text into Emacs

Since my conversion 18 months ago, I've been delaying my quest to find the solution for middle-clicking and getting my text from terminal into Emacs. After some chat in Freenode (thanks to twb)and looking in Google Groups, here's the solution I slapped into my .emacs:


(global-set-key (kbd "") (lambda () (interactive) (insert (x-get-selection 'PRIMARY 'COMPOUND_TEXT))))


UPDATED:
The problem was this line:

(setq x-select-enable-clipboard t)


changed it to:

(setq x-select-enable-clipboard nil)

and now I can paste in from mrxvt, xterm, etc.

Wednesday, October 04, 2006

maven2 junit jvmargs

In the original maven you could put the following line in your project.properties to manage jvm args at testing time:

maven.junit.jvmargs=-server -Dconfiguration.resourceType=properties ... -Xrunjdwp:transport=dt_socket,address=8787,server=y -Xmx512m


In maven2, the easiset way is:

<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>
-server -Dconfiguration.resourceType=properties ... -Xrunjdwp:transport=dt_socket,address=8787,server=y -Xmx512m
</argLine>
</configuration>
</plugin>
</plugins>
</build>
...
</project>

one of the reasons I like maven2

http://www.javaworld.com/javaworld/jw-12-2005/jw-1205-maven-p2.html

Suppose you want to use Hibernate in your project. You would simply add a new dependency to the dependencies section in pom.xml, as follows:


hibernate
hibernate
3.0.3
compile


And that's it! You don't have to hunt around to know in which other JARs (and in which versions) you need to run Hibernate 3.0.3; Maven will do it for you!


That is sweet, and relieves great pain in larger projects with many tendrils to OSS jars.

Adding a custom attribute to the user class in Active Directory, then fetching it via Ruby

(credit: http://www.lacoude.com/docs/public/Attributes.aspx#_ftn8)

First, install adminpak.msi from windows\system32 and then add the following registry key:

Key: HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters
Value: "Schema Update Allowed" = 0x1


Then run schmmgmt.msc. Right click on "Attributes" and "Create Attribute" as the "imsid" attribute, specifiying the x500 oid as created from oidgen.exe. Index it, activate it, and allow it to be shown in advanced view.

Lastly, go to the properties of the "user" class, select the "Attributes" tab. Add an "optional" attribute by finding the "imsid" attribute.

Now, using ADAM-adsiedit.msc, the Administrator can connect to the AD tree and update users' attributes with the appropriate imsids:

Right-click on ADAM ADSI Edit, select "Connect to..."
select "Distinguished name or naming context"
enter "cn=users,dc=devdomain,dc=it,dc=vital" (adjust dc values as necessary)
click "Ok"
expand the tree, find the CN of the user to edit
right-click on user, select "Properties"
find the "imsid" attribute, edit, apply

Done.

Here's the ultra-basic Ruby code that will lookup and print the imsid attribute:

require 'ldap'

host = "192.168.88.20"
port = 389
username = "servuser"
login = "servuser@devdomain.it.vital"
password = "mypassword"
found_imsid = "not_found"
dn = "cn=users,dc=devdomain,dc=it,dc=vital"


connection = LDAP::Conn.new(host,port)
connection.set_option(LDAP::LDAP_OPT_PROTOCOL_VERSION,3)
connection.bind(login, password)

result = connection.search2( dn, LDAP::LDAP_SCOPE_SUBTREE, "cn=#{username}", ["imsid"])

if(result.size == 1)
found_imsid = result.first["imsid"][0]
end

p found_imsid

Tuesday, October 03, 2006

mongrel_cluster startup script for Gentoo


#!/sbin/runscript
#
# Copyright (c) 2006 Bradley Taylor, bradley@railsmachine.com
#
# Updated Oct 2006 by Russell Rollins for Gentoo compliance.
#
# mongrel_cluster Startup script for Mongrel clusters.
#
# chkconfig: - 85 15
# description: mongrel_cluster manages multiple Mongrel processes for use # behind a load balancer.
#

CONF_DIR=/etc/mongrel_cluster
RETVAL=0

depend() {
need net
}

start() {
ebegin "Starting Mongrel cluster"
/usr/bin/mongrel_cluster_ctl start -c ${CONF_DIR}
eend $?
}
stop() {
ebegin "Stopping Mongrel cluster"
/usr/bin/mongrel_cluster_ctl stop -c ${CONF_DIR}
eend $?
}

pound and mongrel_cluster

In order to easily manage the development/deployment via Capistrano, it made sense to also be running mongrel_cluster automatically. This way deployment is real-time with instant results.


gem install mongrel_cluster capistrano --include-dependencies


Then install pound via emerge/yast. Edit the pound.cfg file:
(this still doesn't seem to be working)

ListenHTTP
Address 0.0.0.0
Port 80
Service
BackEnd
Address 0.0.0.0
Port 8000
End
BackEnd
Address 0.0.0.0
Port 8001
End
BackEnd
Address 0.0.0.0
Port 8002
End
Session
Type BASIC
TTL 300
End
End
End


Start pound and add it to startup:


/etc/init.d/pound start
rc-update add pound default



Next, railsapp/config/mongrel_cluster.yml would look like:


cwd: /home/build/deploy/current
port: "8000"
environment: development
address: 0.0.0.0
pid_file: log/mongrel.pid
servers: 3



Initialize capistrano for railsapp:


cap --apply-to /path/to/railsapp MyApplicationName


Now that capistrano has been initialized, update the config/deploy.rb file adding:


set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml"


Update the other properties as necessary, paying particular attention to:


role :web, "someserver.yourinternaldomain.local"


The servers will have to be contactable by the exact name placed in the quotes.

Update the remote variables:


set :deploy_to, "/home/build/deploy"
set :user, "build"
set :keep_releases, 5

Be sure to have the "build" user's password on hand since it'll be necessary for capistrano commands.

Ensure capistrano is working with:


rake remote:exec ACTION=setup


Check that the target server has the releases and shared directories created, if so, capistrano worked.

Lastly:


rake deploy


This should pull everything down and place it in the "current" directory (in relation to cwd).

Create a link to mongrel_cluster script and mongrel_cluster.yml then add to startup:


mkdir /etc/mongrel_cluster
ln -s /home/build/deploy/current/config/mongrel_cluster.yml /etc/mongrel_cluster/railsapp.yml
ln -s /usr/lib/ruby/gems/1.8/gems/mongrel_cluster-0.1.3/resources/mongrel_cluster /etc/init.d/mongrel_cluster
chmod +x /etc/init.d/mongrel_cluster
rc-update /etc/init.d/mongrel_cluster default

TODO: autostart failing on Gentoo

Lastly, start the mongrels:


/etc/init.d/mongrel_cluster start


Test from port 80, 8000, 8001 and 8002 that the rails intro page comes up. Done.