[{"content":"I\u0026rsquo;m Lewis Cawthorne, a Senior Software Developer at EXL. All posts here are my own opinions and are in no way reflective of my employer. Day to day I work on the Subrosource platform: an OSGi backend, an Angular frontend, Microsoft SQL Server, AWS, HashiCorp tooling (Vault, Consul, Nomad), and increasingly, AI-assisted development with tools like GitHub Copilot, Cursor, and Claude Code.\nThis site is built with Hugo using the PaperMod theme, hosted on GitHub Pages. Like every personal site ever built, it is, and will probably always be, a work in progress.\nThe posts here are a mix of old and new. Some are notes from years ago that I moved over when I rebuilt the site, kept as-is for the record.\n","permalink":"http://llcawthorne.github.io/about/","summary":"\u003cp\u003eI\u0026rsquo;m Lewis Cawthorne, a Senior Software Developer at EXL. All posts here are\nmy own opinions and are in no way reflective of my employer. Day to day I\nwork on the Subrosource platform: an OSGi backend, an Angular frontend,\nMicrosoft SQL Server, AWS, HashiCorp tooling (Vault, Consul, Nomad), and\nincreasingly, AI-assisted development with tools like GitHub Copilot,\nCursor, and Claude Code.\u003c/p\u003e\n\u003cp\u003eThis site is built with \u003ca href=\"https://gohugo.io/\"\u003eHugo\u003c/a\u003e using the\n\u003ca href=\"https://github.com/adityatelange/hugo-PaperMod\"\u003ePaperMod\u003c/a\u003e theme, hosted on\n\u003ca href=\"https://pages.github.com/\"\u003eGitHub Pages\u003c/a\u003e. Like every personal site ever\nbuilt, it is, and will probably always be, a work in progress.\u003c/p\u003e","title":"About"},{"content":"You can get in touch with or find me at:\nGitHub LinkedIn Facebook Twitter/X My Daily Fitness Journal on the Nerd Fitness Rebellion forums Or by sending an e-mail to llcawthorne@gmail.com ","permalink":"http://llcawthorne.github.io/contact/","summary":"\u003cp\u003eYou can get in touch with or find me at:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/llcawthorne\"\u003eGitHub\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.linkedin.com/in/llcawthorne\"\u003eLinkedIn\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://facebook.com/llcawthorne\"\u003eFacebook\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://twitter.com/llcawthorne\"\u003eTwitter/X\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eMy \u003ca href=\"https://rebellion.nerdfitness.com/topic/124542-llcawthorne%E2%80%99s-daily-battle-log/\"\u003eDaily Fitness Journal\u003c/a\u003e on the Nerd Fitness Rebellion forums\u003c/li\u003e\n\u003cli\u003eOr by sending an e-mail to \u003ca href=\"mailto:llcawthorne@gmail.com\"\u003ellcawthorne@gmail.com\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e","title":"Contact"},{"content":"Lewis Cawthorne llcawthorne@gmail.com\nSenior Software Developer at EXL, working on the Subrosource platform.\nDegrees Masters of Engineering, Computer Science, University of South Carolina, Columbia, SC, Dec 2014\nSpecialization: Information Security\nBS, Computer Science, University of South Carolina, Columbia, SC, Aug 2011\nMinor: Mathematics\nAS, High Honors, Midlands Technical College, Columbia, SC, May 2009\nProfessional Employment Senior Software Developer and Technical Lead, EXL, Jan 2015 - present\nLong-tenured technical contributor on the Subrosource platform, now over a decade with the team Platform lead for Subrosource Classic (the original Java EE / Oracle-based application) and a contributor on its ground-up replacement, built on an OSGi backend (started on Java 11, now on Java 25) with an Angular frontend, backed by Microsoft SQL Server, hosted on AWS, with infrastructure supported by HashiCorp tooling (Vault, Consul, Nomad) Maintain operation of Subrosource Classic and ensure it gets yearly security patches, in addition to new development work on its replacement, ahead of an eventual customer migration off the older platform Extensive experience with Oracle and PL/SQL; independently designed, wrote, and performance-tuned a large PL/SQL package, including deep dives into Oracle internals to resolve performance issues Using AI-assisted development tools day to day, including GitHub Copilot, Cursor, and Claude Code Took a leading role in an agile group with seven developers acting within a larger corporate organization to provide software and services to insurance domain customers Updated Subrosource Classic from Weblogic 10.3 to Weblogic 12 and from Java 1.6 to Java 1.8 Maintained, extended, and helped secure the Subrosource Classic Java EE 5 application on Oracle WebLogic Application Server and Java 1.6 backed by an Oracle 11g database Performed security scans with HP Fortify software and patched found vulnerabilities Developed a web application to provide insight to support technicians debugging general data import issues with JDK 8 and Java EE 7 technologies running on Glassfish 4.1 Application Server with a Vaadin GWT-based rich user interface accessing an Oracle 11g database and custom scripts to extract text log information Researched and made recommendations on ways to ease development team growth pains by better incorporating automated unit, integration, and acceptance testing Wrote, tested, and debugged a batch process based on preexisting procedural logic to on-board a new customer by cleaning, transforming, and importing 80,000 customer claim records which were split up to over half a million relational table entries; primarily handled through the creation and integration of new awk processing scripts, some modification of a C# account registration program, and PL/SQL customizations in the database to handle customer specific account logic Teaching Assistant, University of South Carolina, Aug 2012 - Dec 2014\nFall 2014: Lecture Instructor for CSCE 212 - Intro to Computer Architecture (Assembly) Summer 2014: Lecture Instructor for CSCE 146 - Data Structures Using Java (Java) Spring 2014: Lecture Instructor for CSCE 212 - Intro to Computer Architecture (Assembly) Fall 2013: Lecture Instructor and Lab TA for CSCE 101 - Intro to Computing (Java) Spring 2013: Lecture Instructor for CSCE 204 - Program Design and Development (Visual Basic) Fall 2012: Lab TA for CSCE 145 - Algorithmic Design (Java) Research Assistant, Center for Information Assurance Engineering at USC, Aug 2011 - Dec 2014\nQuantum Complexity Theory research advised by Dr. Stephen A. Fenner Analyzed algorithms which require quantum computers and how problems solvable via quantum algorithms, such as factoring, differ in structure from classical problems Studied quantum entanglement effects on classic two party game theory Investigated mutually unbiased bases for secure quantum key distribution Expanded a C program for web based analysis and graphing of lambda closure functions including a LaTeX based formula parser REU Program Coordinator, Research Experience for Undergraduates at USC, Aug 2011 - Aug 2013\nCoordinated summer housing and activities for 10 undergraduate participants Guided participants through all steps of creating and submitting an academic paper Offered proofreading and implementation advice on 10 papers from 7 different subareas Undergraduate Research Assistant, MLEG Lab at USC, Jun 2010 - Aug 2011\nCreated SMEE, the Sorting Motif Extraction Engine, a biomedical text analysis service using Python for Natural Language Processing and Django web framework Linux System Administrator, EMR Technical Solutions, Feb 2010 - Jun 2010\nSetup various server applications on three Linux servers Managed security on servers, including detection / elimination of prior intrusion Network Administrator, Wave Communications / Durocom / Volaris Online, June 1995 - Sept 2002\nLead the building of what quickly became a 3000-4000 customer Internet provider Maintained 14 high volume servers running multiple operating systems Participated in a 24-hour emergency response on call rotation Supervised a team of 20-40 technical support representatives Ultimately shared primary responsibility for a $10-million regional ISP with a co-administrator, which was acquired by a super-regional provider and then by Earthlink Database Administrator, Doulos Productions, Apr 1992 - Nov 1996\nCreated and managed a 100,000 record relational database Managed a VM386 based dumb terminal multiuser system Technology Applications and Expertise Current Focus: OSGi, Angular, Microsoft SQL Server, AWS, HashiCorp Vault, HashiCorp Consul, HashiCorp Nomad, AI-assisted development (GitHub Copilot, Cursor, Claude Code)\nSpecialized Skills: Java EE, EJB2, EJB3, JSP, JSTL, JSF, RichFaces, JTA, JPA, Layered Architectures, Agile Development, Information Security, User Testing, Full-stack Web Development, Version Control, Web Design\nMarkup/Programming: Java, Python/Django, JavaScript, JQuery, Ruby/Rails, XHTML, HTML5, CSS, CSS3, XML, XSLT, Perl, Awk, PL/SQL, Shell Scripting\nApplications: Eclipse, IntelliJ, Microsoft Office, HP Fortify Security Scanner, Google Drive, Vim, Oracle 9i-11g, Selenium, Git, Subversion, WebLogic 10.3 - 12, Glassfish 4\nOS/Environments: Mac, Linux, Unix, Ubuntu, Windows\nCertifications CNSS 4011, National Training Standard for INFOSEC Professionals\nAwards Presidential Graduate Fellowship, University of South Carolina, Aug 2012 - Apr 2014 Magellan Scholarship Winner, competitive research funding, Jan 2011 - Aug 2011 Outstanding Senior Award, University of South Carolina, Apr 2011 IBM Master the Mainframe Competition, winner Parts 1 and 2, Dec 2010 ΥΠE Scholarship Winner, competitive scholarship, Aug 2010 Societies ACM, Association for Computing Machinery GCC, Gamecock Cybersecurity Club SLC, STARS Leadership Corps ColaLUG, Columbia Linux Users Group Upsilon Pi Epsilon (ΥΠE) and Phi Theta Kappa (ΦΘK) Honor Societies ","permalink":"http://llcawthorne.github.io/resume/","summary":"\u003ch1 id=\"lewis-cawthorne\"\u003eLewis Cawthorne\u003c/h1\u003e\n\u003cp\u003e\u003ca href=\"mailto:llcawthorne@gmail.com\"\u003ellcawthorne@gmail.com\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eSenior Software Developer at EXL, working on the Subrosource platform.\u003c/p\u003e\n\u003ch2 id=\"degrees\"\u003eDegrees\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003eMasters of Engineering, Computer Science, University of South Carolina, Columbia, SC, Dec 2014\u003c/strong\u003e\u003cbr\u003e\nSpecialization: Information Security\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eBS, Computer Science, University of South Carolina, Columbia, SC, Aug 2011\u003c/strong\u003e\u003cbr\u003e\nMinor: Mathematics\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eAS, High Honors, Midlands Technical College, Columbia, SC, May 2009\u003c/strong\u003e\u003c/p\u003e\n\u003ch2 id=\"professional-employment\"\u003eProfessional Employment\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003eSenior Software Developer and Technical Lead, EXL, Jan 2015 - present\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eLong-tenured technical contributor on the Subrosource platform, now over a decade with the team\u003c/li\u003e\n\u003cli\u003ePlatform lead for Subrosource Classic (the original Java EE / Oracle-based application) and a contributor on its ground-up replacement, built on an OSGi backend (started on Java 11, now on Java 25) with an Angular frontend, backed by Microsoft SQL Server, hosted on AWS, with infrastructure supported by HashiCorp tooling (Vault, Consul, Nomad)\u003c/li\u003e\n\u003cli\u003eMaintain operation of Subrosource Classic and ensure it gets yearly security patches, in addition to new development work on its replacement, ahead of an eventual customer migration off the older platform\u003c/li\u003e\n\u003cli\u003eExtensive experience with Oracle and PL/SQL; independently designed, wrote, and performance-tuned a large PL/SQL package, including deep dives into Oracle internals to resolve performance issues\u003c/li\u003e\n\u003cli\u003eUsing AI-assisted development tools day to day, including GitHub Copilot, Cursor, and Claude Code\u003c/li\u003e\n\u003cli\u003eTook a leading role in an agile group with seven developers acting within a larger corporate organization to provide software and services to insurance domain customers\u003c/li\u003e\n\u003cli\u003eUpdated Subrosource Classic from Weblogic 10.3 to Weblogic 12 and from Java 1.6 to Java 1.8\u003c/li\u003e\n\u003cli\u003eMaintained, extended, and helped secure the Subrosource Classic Java EE 5 application on Oracle WebLogic Application Server and Java 1.6 backed by an Oracle 11g database\u003c/li\u003e\n\u003cli\u003ePerformed security scans with HP Fortify software and patched found vulnerabilities\u003c/li\u003e\n\u003cli\u003eDeveloped a web application to provide insight to support technicians debugging general data import issues with JDK 8 and Java EE 7 technologies running on Glassfish 4.1 Application Server with a Vaadin GWT-based rich user interface accessing an Oracle 11g database and custom scripts to extract text log information\u003c/li\u003e\n\u003cli\u003eResearched and made recommendations on ways to ease development team growth pains by better incorporating automated unit, integration, and acceptance testing\u003c/li\u003e\n\u003cli\u003eWrote, tested, and debugged a batch process based on preexisting procedural logic to on-board a new customer by cleaning, transforming, and importing 80,000 customer claim records which were split up to over half a million relational table entries; primarily handled through the creation and integration of new awk processing scripts, some modification of a C# account registration program, and PL/SQL customizations in the database to handle customer specific account logic\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eTeaching Assistant, University of South Carolina, Aug 2012 - Dec 2014\u003c/strong\u003e\u003c/p\u003e","title":"Resume"},{"content":"This time I\u0026rsquo;m working on reinforcing some of the Spring and Spring Boot knowledge I\u0026rsquo;ve picked up from other videos, while seeing if I can learn a couple of new tricks while at it. I\u0026rsquo;m watching Spring Framework Essentials through my Safari Books Online membership. It\u0026rsquo;s presented by Ken Kousen, who often hosts the Groovy Podcast. He has a series of three Groovy videos in Safari Books Online that I wouldn\u0026rsquo;t mind going through sometime in the future. The video series runtime is 5 hours, 14 minutes and it has a five star rating from 35 reviewers. Not bad, let\u0026rsquo;s see what it covers.\nSo, these videos are going to focus on the core Spring Framework. So we won\u0026rsquo;t be getting back into Spring Data or even Spring MVC in this video series. It says that it will talk a little about Spring Boot, since that\u0026rsquo;s the general way to get projects started these days. \u0026ldquo;One thing that you\u0026rsquo;ll notice about the Spring Framework, is that they never met a class or package name too long.\u0026rdquo; Tell me about it. Spring makes you appreciate autocomplete. He uses gradle to manage projects, which is fine. Maven or gradle are both fine options.\nHe did a fine demonstration of basic injection in XML, annotations, and Java config setup and quick intro to aspect oriented programming that included an example of the @Around advice. Then he gave a quick introduction to Spring testing. Finally someone that doesn\u0026rsquo;t ignore testing. It turns out you can annotate you test class with @RunWith(SpringJUnit4ClassRunner) to have Spring aware tests, and you can add the @ContextConfiguration(classes = AppConfig.class so that you have a cached ApplicationContext shared between tests in the class and the ability to @Autowire any of your beans. You can even @Autowire an ApplicationContext ctx variable to inject a reference to your ApplicationContext to use in tests to fetch beans you don\u0026rsquo;t autowire. The fact that @ContextConfiguration takes a classes argument lets you have a different configuration class for tests than the running application if necessary. You can also add the @Transactional annotation to your test class to make all your tests occur in a transaction that gets rolled back after test completion. His toy app that he used to demonstrate early principles didn\u0026rsquo;t have any database interaction to show-off transactional tests, but this is the part of the course that he switches from a toy app to something a little more complicated. He also mentions that the Spring pet-clinic demo app makes good use of transactional tests.\nThe new application has a Service and a Repository interface. Instead of using Spring Data, he does all the database operations with an in-memory and a JDBC implementation. Everything is marked @Transactional at the Service level. He had to makea \u0026ldquo;transactionManager\u0026rdquo; Bean and use an @EnableTransactionManagement on his Configuration class, neither of which I recall being required when doing a Spring Boot app with @Transactional. The JDBC is using the Spring JDBC Template and is a lot cleaner than straight JDBC. The JDBC Template does a lot of work for you. For example, the following one-liner works for getting a count: int rowCount = this.jdbcTemplate.queryForObject(\u0026quot;select count(*) from t_actor\u0026quot;), Integer.class); I like the way he looks up what he is talking about in the online API, the same way you likely would when programming with the various API elements. He shows off using \u0026ldquo;test\u0026rdquo; and \u0026ldquo;prod\u0026rdquo; profiles to differentiate between an H2 in-memory database and an Apache data connection pool backed by MySQL. Each repository method with the JDBC Template ends up being two to four lines long, depending upon what he\u0026rsquo;s try to do. Pretty simple, but not as simple as not defining implementation methods with Spring Data JPA.\nYay! More testing. This time we\u0026rsquo;re testing repositories. Just set the annotations on the test class and annotate the test profile, then autowire the repository and your good to go. Each test is transactional, so they roll back changes at the end of each test. He uses Hamcrest matchers, so he can make assertions like assertThat(accounts.size(), is(3));, which flows a bit better than standard assertEquals. He points out that since he is using gradle he can show the really cool gradle test report. The tests he ran were all quick, even with firing up and setting up the in-memory database. First one took half a second, but the all six of them took less than a second total. He succeeded in exercising all his repository methods and making sure they worked as expected.\nI was wrong that we weren\u0026rsquo;t going into Spring Data. He reimplements his repository using Spring Data JPA for the next project. Spring Data JPA repositories are just interfaces. You get queries generated for free based upon how you name the methods in the interfaces. You can also use the @Query annotation above a method in the interface to give it a custom query if the autogenerated language can\u0026rsquo;t handle what your after. He defined the JpaVendorAdapter and LocalContainerEntityManagerFactoryBean manually in the Java Spring configuration file, which normally weren\u0026rsquo;t require with Spring Boot. It\u0026rsquo;s interesting to see how this is all done by hand, and it isn\u0026rsquo;t that much in total lines of configuration. He didn\u0026rsquo;t use the feature of Spring Data JPA to allow repository autogeneration of methods and just defining an interface. Instead he defined a JpaAccountRepository that implemented its various methods directly through an EntityManager. He does use @PersistenceContext annotation to inject his EntityManager. Most of the methods now are one or two lines long. He did have to add JPA annotations to his entity class, but most of them defaulted through good name selection for class and fields. Only @Entity on the class and @Id on the primary key field actually needed to be added to the domain object. He shows that you can use the same service with the JPA repository as was used with the JDBC Template repository, since he designed the methods to take the same arguments. He uses the same tests also, which makes sense as the interface and expected outputs are the same.\nI forgot to mention it earlier, but this presenter uses IntelliJ for everything. Always nice to see! Oh, he was just using JPA in the last project. The next project is where he\u0026rsquo;s adding in Spring Data to get the free implementations of DAO methods. So, it turns out he uses Spring Data for the last 12 minute segment of the presentation, and then switches to showing the same app with Spring Boot for the last 15 minutes of the presentation. The app keeps getting simpler each time he introduces more Spring features. He actually extended JpaRepository for his repository, where I am more accustomed to seeing CrudRepository or PagingAndSortingRepository extended. JpaRepository extends both. He had to change the method names in his service and tests to match the ones freely given by having an interface extend on of the Spring Data interfaces, but got to delete a lot of code that was the repository class implementation and previous repository interface which was more complicated. Interesting to see that his tests run quicker now too, taking a little under 0.4 seconds. He\u0026rsquo;s still using an H2 in-memory database for testing and setting it up with the same sql scripts. He points out that all his earlier work really was unnecessary. The final project is to show how much of his configuration he can get rid of also by using Spring Boot. It\u0026rsquo;s still interesting to know how to do it by hand, since everything we\u0026rsquo;ve seen is still happening under the hood in Spring Boot.\nSo, at the end, he claims that a Spring Boot focused course is coming. I don\u0026rsquo;t see it as available yet. He had mentioned earlier this video course would be the start of a series. I really enjoyed Ken\u0026rsquo;s presentation, and would definitely watch more in this series by him. It was a neat change seeing Spring used for non-web apps. I hope in the future videos he shows off Spring MVC though, because Spring makes some nice web apps too. He recommends the book Spring Boot in Action at the end, but I found that book fairly worthless. The source code for it didn\u0026rsquo;t match up with what was described in the text. Maybe now that I actually have a grasp on some of this stuff, it would be useful and I could figure out why the sample source code and the text don\u0026rsquo;t match up. Anyway, despite his poor book recommendation at the end, I really enjoyed this video series. It\u0026rsquo;s worth a watch if your looking for something to view with your Safari Books Online membership.\n","permalink":"http://llcawthorne.github.io/posts/oreilly-spring-framework-essentials/","summary":"\u003cp\u003eThis time I\u0026rsquo;m working on reinforcing some of the Spring and Spring Boot\nknowledge I\u0026rsquo;ve picked up from other videos, while seeing if I can learn\na couple of new tricks while at it.  I\u0026rsquo;m watching\n\u003ca href=\"https://www.safaribooksonline.com/library/view/spring-framework-essentials/9781491942680/\"\u003eSpring Framework Essentials\u003c/a\u003e through my Safari Books Online membership.\nIt\u0026rsquo;s presented by Ken Kousen, who often hosts the Groovy Podcast.  He has a\nseries of three Groovy videos in Safari Books Online that I wouldn\u0026rsquo;t mind\ngoing through sometime in the future.  The video series runtime is 5 hours,\n14 minutes and it has a five star rating from 35 reviewers.  Not bad, let\u0026rsquo;s\nsee what it covers.\u003c/p\u003e","title":"O'Reilly Spring Framework Essentials"},{"content":"I figured since I am a professional Java programmer that I might as well spent some time getting familiar with some Java technologies that I don\u0026rsquo;t get to use at work. With this in mind, I purchased Udemy\u0026rsquo;s \u0026ldquo;Spring Boot Intro\u0026rdquo; course for $10 when they had a sale.\nThis course moved a lot quicker than the last course I took from Udemy. It covered basic dependency injection in Spring in probably an hour or less, where the last class focused on dependency injection fundamentals for the entire time. I appreciated the faster pace, as there\u0026rsquo;s a lot of stuff to cover with Spring Boot. It handles autoconfiguring all the main projects that make up Spring\u0026hellip; Spring MVC, Spring Rest, Spring Data, Spring Security, etc.\nThis author made it really hard to code along with him. He did things like restart a project with unknown initialzr settings in between videos. He also copied and pasted a lot of code, so you couldn\u0026rsquo;t really type along with him. As long as you don\u0026rsquo;t mind pausing and typing something in, it wasn\u0026rsquo;t unworkable, but it got a little old. I ended up checking out his repo of code samples and following along with them. He does have exercises at the end of each section, which are a good chance to code some stuff up on your own. He doesn\u0026rsquo;t mention specifically when he changes projects from the repo either, so it\u0026rsquo;s a little hit and miss making sure your looking at the right code that he\u0026rsquo;s working on.\nOne nice thing is this guy used IntelliJ instead of Eclipse. He admitted that you need the paid for version to work with Spring, but just told people to sign up for the 30 day trial. Fortunately, I still have my student license, so I had all the features to play along. It might be annoying to people that have already done the IntelliJ trial, since it makes it harder to follow along. Of course, he\u0026rsquo;s pretty hard to follow along with as it is, so using STS or Eclipse wouldn\u0026rsquo;t be that much worse. Anyway, I was excited at first that he used IntelliJ, but then he switched to Eclipse STS halfway through the videos. I kept following along in IntelliJ.\nI liked the Spring Boot way of doing apps. It felt like convention over configuration brought to the Java world, the way it autoconfigures so much stuff based upon what it finds loaded in your class path. I really liked Spring Data, which allows you to pair up standard JPA entities with Repository interfaces that automatically generate the implementation with queries based upon the names of the method defined in your interface.\nFor example, if you make a method called findByLastName(String lastName) in your interface, you get the query you would expect for free. The instructor didn\u0026rsquo;t go into this, but it also works with QueryDSL predicates to fill in the queries, which is pretty cool since I use QueryDSL at work. He also showed how to do everything by hand with JDBC, but I liked the JPA approach better. He also showed that you can drop in mongo DB and swap out Entity annotation for Document pretty easily in an app with very little changes. It was a weird choice doing JPA backed by a Microsoft SQL Server database, and since I didn\u0026rsquo;t feel like signing up for an Azure trial, I just kept using H2.\nI really liked the Dev Tools with live reload. He showed that you have to change a few settings in IntelliJ. In the registry you check compiler.automake.allow.when.app.running and in the Preferences-\u0026gt;Build, Execution, Deployment-\u0026gt;Compiler you check the Build project automatically. Then you install a browser extension from http://livereload.com/extensions/ and it will reload automatically when anything changes in your code. It isn\u0026rsquo;t that much work really to save hitting refresh all the time. He doesn\u0026rsquo;t use that in most of his projects, but I kept it turned on in all the ones I did by hand.\nI like Spring Security, but found the course\u0026rsquo;s presentation of it to be a little light. It does explain how you get free security headers, some XSS prevention, and CSRF tokens just by including Spring Security, and in his example he works up to a custom login form backed by a database (this time MySQL) of users, but he stores the passwords in plain text, so his app wouldn\u0026rsquo;t be that useful a model to look at if I ever wanted to do this for real.\nThe REST presentation was more thorough than it needed to be. It seems like every talk about REST has to go over what the different status codes mean first thing. Why not just link out to HTTP Status Cats website. I want to know how he gets his JSON formatted so pretty in the browser. I\u0026rsquo;m sure it\u0026rsquo;s a plugin, but it isn\u0026rsquo;t one I already have. Oh, he finally mentioned what it is during the REST videos. \u0026ldquo;JSON Viewer\u0026rdquo; extension for Chrome. Nice. Anyway, I thought REST frameworks were easy to setup when we were doing them the hard way (RestController annotations and services), but it turns out you can get rid of your controllers and services and directly expose your repo through a default build REST API if you don\u0026rsquo;t need a lot of custom logic. There\u0026rsquo;s even a built in HAL Browser for discovery and interaction with the API, if you choose to include it. HAL Browser dependency comes from org.springframework.data and not org.springframework.boot. That tripped me up for a minute in the exercises.\nFor the final series of lectures, he expects you to work along with him starting from an initial setup. We\u0026rsquo;ll see if this works any better\u0026hellip; Nope! He still does a lot of stuff off-screen between videos. Anyway, the final project is a blogging website. It uses bootstrap to look good, thymeleaf for the templates, spring data jpa for the database interaction, and spring security to enforce editing only by those with admin level privileges. I still need to read the docs on thymeleaf templates to feel like I know much about them, since he always provides the templates and doesn\u0026rsquo;t explain much. They look pretty simple. Extra attributes to HTML tags causes you to override content that is present in the source and do other modificiations. Like \u0026lt;span sec:authentication=\u0026quot;name\u0026quot;\u0026gt;Guest\u0026lt;/span\u0026gt; will default to Guest, but will override that value with the name of whoever is currently authenticated. Judging from the upcoming titles, he\u0026rsquo;s going to throw in some validation, which is a topic he hasn\u0026rsquo;t covered in the previous sections.\nI couldn\u0026rsquo;t get his instructions for customizing validation messages to work at all. I got validation working pretty good with the default error messages at least. He claims you just need to put your custom messages in a messages.properties file, but I did that and they didn\u0026rsquo;t get picked up. I assume I have to do something to get it to look in message.properties. Everyone on stack overflow with a related problem seems to be running WAR\u0026rsquo;s, so those questions don\u0026rsquo;t seem to apply to my setup. I\u0026rsquo;ll dig in the documentation later and see what\u0026rsquo;s going on.\n","permalink":"http://llcawthorne.github.io/posts/udemy-spring-boot-intro/","summary":"\u003cp\u003eI figured since I am a professional Java programmer that I might as well\nspent some time getting familiar with some Java technologies that I don\u0026rsquo;t\nget to use at work.  With this in mind, I purchased Udemy\u0026rsquo;s \u0026ldquo;Spring Boot\nIntro\u0026rdquo; course for $10 when they had a sale.\u003c/p\u003e\n\u003cp\u003eThis course moved a lot quicker than the last course I took from Udemy.\nIt covered basic dependency injection in Spring in probably an hour or less,\nwhere the last class focused on dependency injection fundamentals for the\nentire time.  I appreciated the faster pace, as there\u0026rsquo;s a lot of stuff\nto cover with Spring Boot.  It handles autoconfiguring all the main projects\nthat make up Spring\u0026hellip;  Spring MVC, Spring Rest, Spring Data, Spring Security,\netc.\u003c/p\u003e","title":"Udemy - Spring Boot Intro"},{"content":"Chapters 3 through 5 focus on a little bit of theory before we get to building the tutorial application.\nChapter 3 - The Architecture of Rails Applications Chapter 3 jumps into explaining MVC. It\u0026rsquo;s a pretty simple concept. MVC stands for Model, View, and Controller. The model is responsible for the state of the application, often the data you store in a database. It\u0026rsquo;s also more than data; it enforces the business rules that apply to your data. The model is both a gatekeeper and a data store. The view is responsible for generating some type of user interface. The view\u0026rsquo;s job is done once the data is displayed. Multiple possible views of the same data are a common case. The controller orechestrates the application. Controllers receive events from the outside world, interact with the model, and display the appropriate view. The book provides a simple diagram:\nThere\u0026rsquo;s a fine introductory article on Wikipedia if the concept is new to you. One of the main advantages is that each concept or action can be expressed in a single, well-known place. Like many modern web frameworks, Rails is designed with MVC in mind. Rails first sends your request to a router, which then maps it to a method of a controller (called an action), and then the action looks at data in the request to decide how to interact with the model and ultimately it prepares information for the view, which renders the result.\nThe request contains a path (/line_items?product_id=2) and a method (GET, POST, PUT, PATCH, DELETE). By default rails takes the first part of the path, line_items, as the controller name and the product_id as the ID of a product, which it passes to the create() method of a LineItemsController if we assume this is a POST request. Different types of request are routed to different methods of the controller.\nRails handles a lot of the low level details of an MVC app, so you can focus on the core application logic. One example of this is in its ORM (object- relational mapping) libraries which map database tables to classes. If you have a class called Order, you know it maps to a database table called orders. The Order object has methods to set all the data fields in the orders table. The Rails classes also wrap our database tables with class-level methods that perform table-level operations. For example, you might want to look up an Order by ID. Code to do so might look like:\norder = Order.find(1) puts \u0026#34;Customer #{order.customer_id}, amount=$#{order.amount}\u0026#34; Or you could have a class level method that searches by a where clause and returns a collection of objects:\nOrder.where(name: \u0026#39;dave\u0026#39;.each do |order| puts order.amount end In addition to accessing field values, you can set values via the object and then save it to the database:\nOrder.where(name: \u0026#39;dave\u0026#39;).each do |order| order.pay_type = \u0026#34;Purchase order\u0026#34; order.save end So an ORM layer maps tables to classes, rows to objects, and columns to attributes of those objects. Class methods are used to perform table-level operations, and instance methods perform operations on individual rows. Active Record is the ORM layer provided by Rails. It relies on convention over configuration and starts with sensible defaults to minimize manual configuration by developers.\nAction Pack is the part of Rails that supports the views and controllers. At its simplest, the view is a chunk of HTML code that displays some static content, but you normally want dynamic content generated by templates. Rails offers templates in three flavors:\nEmbedded Ruby (ERB), which is the most common, embeds snippets of Ruby within an HTML document ERB used to construct JavaScript fragments on the server to execute in the browser to form the view an XML builder to construct XML documents using Ruby code. The controller acts as the logical center of an application, coordinating interaction among the user, the views, and the model. It\u0026rsquo;s responsible for routing URLs to actions, it manages caching, it manages helper modules, and it also manages sessions. The way Rails handles most of the interaction behind-the scenes makes controller code easy to develop and maintain.\nChapter 4 - Introduction to Ruby All of Chapter 4 is focused on a quick review of Ruby. I\u0026rsquo;ld recommend a refresher at learnxiyminutes if your Ruby is a little rusty or checkout the zenspider quickref.\nThe one thing those don\u0026rsquo;t cover that is relevant is YAML (YAML Ain\u0026rsquo;t Markup Language). YAML is used to define configuration of things in Rails.\ndevelopment: adapter: sqlite3 database: db/development.sqlite3 pool: 5 timeout: 5000 Indentation is import in YAML, and the above snippet defines four key-value pairs.\nChapter 5 - The Depot Application Chapter 5 focuses on the design of the application that is being built in the upcoming tutorial chapters. We\u0026rsquo;re going to build a basic bookstore, based upon the Pragmatic Bookshelf website. It approaches the problem from a mindset of incremental development and starts out from basic back-of-the-napkin style sketches of functionality. It points out that Ruby on Rails shines for this style of development, because it doesn\u0026rsquo;t heavily penalize changing your mind about something mid-development. It also points out that we\u0026rsquo;ll be building tests as we go. Yay!\nTo start with, we want an outline of how the application will work at a high level. We identify two roles: the buyer and the seller. The buyer browses for products, selects some to purchase, and creates an order. The seller uses the application to maintain a list of products to sell, to determine order awaiting shipment, and to mark orders shipped. Here is a first sketch of the buyer flow:\nIt\u0026rsquo;s a pretty traditional and simple flow. There\u0026rsquo;s also the seller flow:\nIn both cases, we\u0026rsquo;re not overspecifying things we are unsure about, like details of the shipping method or payment methods. We also need to think about what the data is going to look like:\nThere\u0026rsquo;s obviously some questions left, like what goes in cart, but this is enough to get started, and we can figure out the other details once we\u0026rsquo;re in a better position of knowledge later after we\u0026rsquo;ve started. With these diagrams in hand to get us started and an imaginary customer to show our progress, we\u0026rsquo;re ready to get started on the book\u0026rsquo;s tutorial application.\n","permalink":"http://llcawthorne.github.io/posts/awdwr51-03-05-theory/","summary":"\u003cp\u003eChapters 3 through 5 focus on a little bit of theory before we get to\nbuilding the tutorial application.\u003c/p\u003e\n\u003ch3 id=\"chapter-3---the-architecture-of-rails-applications\"\u003eChapter 3 - The Architecture of Rails Applications\u003c/h3\u003e\n\u003cp\u003eChapter 3 jumps into explaining MVC.\nIt\u0026rsquo;s a pretty simple concept.  MVC stands for Model, View, and Controller.\nThe \u003cem\u003emodel\u003c/em\u003e is responsible for the state of the application, often the data\nyou store in a database.  It\u0026rsquo;s also more than data; it enforces the business\nrules that apply to your data.  The model is both a gatekeeper and a data\nstore.  The \u003cem\u003eview\u003c/em\u003e is responsible for generating some type of user\ninterface.  The view\u0026rsquo;s job is done once the data is displayed.\nMultiple possible views of the same data are a common case.  The\n\u003cem\u003econtroller\u003c/em\u003e orechestrates the application.  Controllers receive events from\nthe outside world, interact with the model, and display the appropriate\nview.  The book provides a simple diagram:\u003c/p\u003e","title":"AWDWR 5.1 - 03-05 - Theory"},{"content":"I\u0026rsquo;m still going back to finish my Agile Web Development with Rails 5.1 series. I finished reading the main project in the book a while back now. I just haven\u0026rsquo;t made time with the computer to create the demo project, and I want to have it in a repo to upload and talk about the code a little. I didn\u0026rsquo;t read the reference chapters, since they were still incomplete. I think I\u0026rsquo;ll read Agile Web Development with Rails 5 on Safari Books in its entirety, and that will give me a good perspective to see what changes with the project in the Rails 5.1 version of the book. The only thing that I noticed so far that was 5.1 specific is the ActionCable Websocket stuff they throw in, so that if a price changes on the backend it pushes the update to customers. Pretty neat to see Websockets used for something so small, instead of big examples of chat servers and what not like you commonly see.\nI\u0026rsquo;ve read several things since finishing Agile Web Development with Rails 5.1. One I might dedicate multiple blogposts to: \u0026ldquo;Practical Object-Oriented Design in Ruby\u0026rdquo;. It was really good, and I highlighted large sections of the book that are worth talking about. Some of the stuff I had seen before in places like \u0026ldquo;Clean Code\u0026rdquo; and in my Software Engineering class, but it had a lot of good direct advice on designing things properly from an object-oriented perspective. The examples were in Ruby, but it didn\u0026rsquo;t linger much on language specifics.\nSpeaking of Ruby, I\u0026rsquo;ve been refreshing my Ruby skills after spending time with the Agile Web Development in Rails 5.1 book and before delving into some other Rails books (primarily Hartl\u0026rsquo;s \u0026ldquo;Ruby on Rails Tutorial: Learn Web Development with Rails\u0026rdquo; which I read in an old version and the new rough cut of \u0026ldquo;The Rails 5 Way\u0026rdquo; ). I re-read the 10th anniversary edition of the Pickaxe , since I had a hardcopy of it on the shelf. That link takes you to the fourth edition, rather than the 10th anniversary edition. It was focused on Ruby 1.9. Then I re-read Why\u0026rsquo;s (Poignant) Guide to Ruby. It\u0026rsquo;s a little dated, but still relevant. And finally for something a little more up to date, I started reading the latest edition of \u0026ldquo;The Ruby Way\u0026rdquo;.\nI like the Pickaxe best for a fast moving introduction to the language that is worth a couple of reads, paired with detailed chapters on various topics relating to Ruby in its setting. Why\u0026rsquo;s guide is classic, and gets into some neat metaprogramming topics, although it has a lot of charmingly weird stuff in it and not so much code. \u0026ldquo;The Ruby Way\u0026rdquo; is starting to feel like a bit of a slog to make it through reading from cover to cover. It feels like it would be a handy desk reference, but from a reader\u0026rsquo;s perspective, do I really want to read how to build a GUI using five different libraries back-to-back. It was good for establishing a comparison of several different ways to do GUI stuff at least. I think I\u0026rsquo;ll try out Shoes. Anyway, so now I feel like I know Ruby again, and I\u0026rsquo;ve been using it for Code Wars to get lots of practice with toy problems.\nOh, I\u0026rsquo;ve also signed up for a MOOC that teaches Software Engineering concepts with Rails. Agile Development Using Ruby on Rails - Basics. I signed up for the matching advanced course too. So, if you want more Rails material, I have some coming up to write about at least. I\u0026rsquo;ll write my opinion of the MOOC after I get a chance to watch through the videos and try the exercises. Between the MOOC and the other Rails books I have on my reading list, I should get a couple of nice blogposts that have some code blocks in them. Now that I have syntax highlighting working, might as well use it. There\u0026rsquo;s also an Infinite Skills video that I have access to through Safari Books Online that I wouldn\u0026rsquo;t mind trying out. Hands-on with React and Ruby on Rails. I don\u0026rsquo;t have much React experience past doing the Tic-Tac Toe tutorial, but I can probably manage it as the video doesn\u0026rsquo;t claim you need React experience. Anyway, I\u0026rsquo;ll get back to reading and watching and coding stuff now, and come back with some blogposts that include code soon.\n","permalink":"http://llcawthorne.github.io/posts/misc-reading/","summary":"\u003cp\u003eI\u0026rsquo;m still going back to finish my Agile Web Development with Rails 5.1\nseries.  I finished reading the main project in the book a while back\nnow. I just haven\u0026rsquo;t made time with the computer to create the demo\nproject, and I want to have it in a repo to upload and talk about\nthe code a little.  I didn\u0026rsquo;t read the reference chapters, since\nthey were still incomplete.  I think I\u0026rsquo;ll read Agile Web Development\nwith Rails 5 on Safari Books in its entirety, and that will give me a\ngood perspective to see what changes with the project in the Rails 5.1\nversion of the book.  The only thing that I noticed so far that was 5.1\nspecific is the ActionCable Websocket stuff they throw in, so that if a price\nchanges on the backend it pushes the update to customers.  Pretty neat\nto see Websockets used for something so small, instead of big examples\nof chat servers and what not like you commonly see.\u003c/p\u003e","title":"Misc Reading"},{"content":"So, I promised I\u0026rsquo;ld mention what goodies I find in the second half of Practical Vim, 2nd Edition. Here they are.\nChapter 10, Copy and Paste First, the repetition of the insert mode \u0026lt;C-r\u0026gt;{register} command later in the book was something I found useful. I think that\u0026rsquo;s a pretty handy way to paste the contents of a register. I never knew that \u0026quot;+ let\u0026rsquo;s you access the system clipboard either. If you put the two together, you can quickly paste from the system clipboard without leaving insert mode with \u0026lt;C-r\u0026gt;+. The fact that yank stores a copy of what it copies in the 0 register is pretty handy too. Nice to have an alternate way to access the last yank if I\u0026rsquo;ve clobbered it.\nChapter 11, Macros Most of the macros chapter was fairly new to me. I knew the basics of how to record and playback macros, and have used them before when in native vim and not using an emulator. But I\u0026rsquo;ve never given macros intense thought or tried to be terribly clever with them. He goes into the idea of crafting resilient reusable macros in some depth in the tips focused on them and covers a handful of macro best practices. As he puts it, \u0026ldquo;The golden rule is this: when recording a macro, ensure that every command is repeatable.\u0026rdquo;\nThe author sums up macro advice with the phrase \u0026ldquo;Normalize, Strike, Abort\u0026rdquo; The first question to ask when crafting a macro is, \u0026ldquo;where am I, where have I come from, and where am I going.\u0026rdquo; Make sure the cursor is positioned so the next command does as expected where expected. You shouldn\u0026rsquo;t use the mouse when recording a macro, so make sure to take advantage of the full range of available motion commands to maneuver to the right location to strike. If a motion fails while a macro is executing, Vim will abort the rest of the macro. This is a feature! You don\u0026rsquo;t want to execute your command when you aren\u0026rsquo;t in the right location. Motions can act as a simple test as to whether or not the macro should be executed. Remember that search is a motion too. You can do a lot with a macro that uses the n key to go to the next search item and perform an action. Once no matches remain, n will fail and the macro will stop.\nTip 67 points out how a simple two key macro can be useful to move and perform the dot command multiple times. You can\u0026rsquo;t repeat with dot, and if you could the number would either repeat the move multiple times or repeat the dot multiple times in the same place, so a simple macro of a movement command and dot is a clever trick tie a move and repeat together and replay it multiple times. Again, you can count on the motion failing at the end if you choose the right motion, so you don\u0026rsquo;t have to worry about the exact count. The example is as follows:\n{start} x = \u0026ldquo;(\u0026quot;+a+\u0026rdquo;,\u0026quot;+b+\u0026quot;,\u0026quot;+c+\u0026quot;,\u0026quot;+d+\u0026quot;,\u0026quot;+e+\u0026quot;)\u0026quot;;\nAnd we want to change it to:\n{goal} x = \u0026ldquo;(\u0026rdquo; + a + \u0026ldquo;,\u0026rdquo; + b + \u0026ldquo;,\u0026rdquo; + c + \u0026ldquo;,\u0026rdquo; + d + \u0026ldquo;,\u0026rdquo; + e + \u0026ldquo;)\u0026rdquo;;\nAnd it can be achieved with the following keystrokes:\nf+ s + \u0026lt;Esc\u0026gt; qq;.q 22@q That\u0026rsquo;s much simpler than adding the spaces around the + marks by hand. Since the f+ movement will fail after we are out of +\u0026rsquo;s, it is safe to run the macro 22 times. The author admits to being lazy like this often. 22 is his go to repeat number, since 2 is the same key as @ to run the macro. That\u0026rsquo;s a great example of making use of \u0026ldquo;Abort\u0026rdquo;.\nAppending keystrokes to macros works just like appending yanks to registers. qA will append commands on the end of the macro in register a. That\u0026rsquo;s a small but handy tip for getting more from macros. The next tip covers how to apply a macro to a series of files, either with :argdo normal @a or by manually advancing with :next to act across the argument list. The example he uses is a pretty handy one of wrapping several classes in a module declaration and adding proper indentation. The next tip seems handy, but I doubt it\u0026rsquo;s general enough use for me to remember it. It covers how to prepend an incrementing line count to multiple lines. The final tip of the chapter covers the fact that you can put a macro from a register, then edit the macro text, then yank the macro back to the register. An interesting option for editing macros! One note is to be careful to use a character-wise yank like \u0026quot;ay$\u0026quot;, or else you might get an extra \u0026lt;CR\u0026gt; at the end of your macro.\nChapter 12 - Matching Patterns and Literals First off, I learned the handy tidbit that using \\c in a search pattern causes it to ignore case, and \\C to be case sensitive, regardless of ignorecase settings. You can put them anywhere in the pattern, including just tacking them on the end. I like the default smartcase where if you include an uppercase letter it is case sensitive, otherwise not.\nThe \\v switch anywhere in a regex makes it \u0026ldquo;very magic\u0026rdquo;, or more like what you might be used to from Perl, Python, or Ruby. It makes all characters assume a special meaning except for \u0026ldquo;_\u0026rdquo;, letters, and numbers, so you don\u0026rsquo;t need to escape all your braces, brackets, and parentheses. It makes the difference between #\\([0-9a-fA-F]\\{6}\\|[0-9a-fA-F]\\{3}\\) and \\v#([0-9a-fA-F]{6}|[0-9a-fA-F]{3}) to match CSS color codes, a regex that can be made slightly even better using the \\x hex class as \\v#(\\x{6}|\\x{3}). The \\V or verynomagic option makes a search only search by the literal meaning of symbols provided, even ., *, and ?. Only the \\ character has special meaning in a verynomagic search. So ultimately, both the \\v and \\V search options are terribly useful and worth remembering. A good example of the \\V option is searching for \u0026ldquo;a.k.a.\u0026rdquo; with /\\Va.k.a. instead of /a\\.k\\.a\\. I think the argument has won me over well enough to use \\v most of the time and \\V on special occassions.\nAnother handy fact for regular expressions is that in verymagic search mode, the \u0026lt; and \u0026gt; keys match word boundaries. So a search for \\v\u0026lt;the\u0026gt; will find all the \u0026ldquo;the\u0026rdquo; occurrences without any \u0026ldquo;their\u0026rdquo; or \u0026ldquo;these\u0026rdquo; being matched. It goes on to cover some ways to handle search field terminators in the final tip of the chapter.\nChapter 13 - Searching, 14 - Substitution, 15 - Global Commands I didn\u0026rsquo;t find anything in these to chapters particularly worthwhile, except the fact that you can leave the search part of a substitute command blank to use whatever the last successful search was as the pattern. That decouples findint the right search pattern from the overall substitute command, and you normally want to search first anyway to make sure you got your pattern right before making changes. The search and replace across a project tip was possibly useful. Everything about the global command was new to me and worth playing with.\nChapter 16 - Index and Navigate Source Code with ctags This whole chapter is about ctags and was all new to me. It looks like an excellent way to get the ability to jump to definitions in vim. Apparently I\u0026rsquo;ve been living under a rock, since I was unaware of this feature. This looks like a key step into making Vim into a development environment instead of just an editor.\nChapter 17 - Compile Code and Navigate Errors with the Quickfix List The quickfix and location lists seem handy, assuming you map navigating them to something more convenient than typing :cnext and :cprev. I\u0026rsquo;ll have to checkout the unimpaired plugin he mentions that makes the quicklist navigable by [q and ]q. It has a number of other handy mappings, so it\u0026rsquo;s worth checking out instead of just putting the one set of mappings in my vimrc. I think I\u0026rsquo;ll use the Tip 108 that has you make :make run JSLint and populate the quickfix list with any linting errors. I didn\u0026rsquo;t fully understand how to do it from the tip, but this github project looks useful: vim-nodelist.\nChapter 18 - Search Project-Wide with grep, vimgrep, and Others There\u0026rsquo;s so many neat random things in this book. Today I learned that there\u0026rsquo;s a version of grep optimized for programmers called ack. Ack. To relate it back to vim, the book explains how to make the vim :grep command use ack instead, but then tells you not to, since there is an ack plugin for vim ack.vim that will use it with the :ack command.\nChapter 19 - Dial X for Autocompletion There\u0026rsquo;s plugins for better autocompletion than what\u0026rsquo;s built in. It looks like you can complete based off ctags with \u0026lt;C-x\u0026gt;\u0026lt;C-]\u0026gt; or use \u0026lt;C-x\u0026gt;\u0026lt;C-i\u0026gt; to complete based off your imports in various languages. Generic autocompletion is based off \u0026lt;C-n\u0026gt; and is probably best of the built-ins. You use \u0026lt;C-n\u0026gt; and \u0026lt;C-p to choose next or previous.\nChapter 20 - Find and Fix Typos with Vim\u0026rsquo;s Spell Checker This one starts out simple, with how to use the built in spell checker. First think I learned is that z= on a misspelled word will bring up suggestions and [s and ]s let you jump between misspelled words. I was able to try those out successfully while writing this blog post. zg adds a word to the spell file, which worked great to add \u0026ldquo;blog\u0026rdquo;. Apparently, you can fix misspelled words without leaving Insert mode with \u0026lt;C-x\u0026gt;s to enable autocomplete misspelled mode. It will jump you back to the last misspelled word and offer suggestions from the dictionary. Pretty handy!\nSummary Overall, I think I picked up more tips than I can reasonably integrate into my workflow at once from my first reading of Practical Vim, Second Edition. That\u0026rsquo;s why I put a lot of them here on my blog, to remind me to try them out. I believe there\u0026rsquo;s still enough that I didn\u0026rsquo;t mention to make the book worth another read, or at least a re-read several spots in it. I highly recommend it if you are already comfortable using Vim and want to pickup tricks to take your Vim workflow to the next level.\n","permalink":"http://llcawthorne.github.io/posts/practical-vim-2/","summary":"\u003cp\u003eSo, I promised I\u0026rsquo;ld mention what goodies I find in the second half of\nPractical Vim, 2nd Edition.  Here they are.\u003c/p\u003e\n\u003ch2 id=\"chapter-10-copy-and-paste\"\u003eChapter 10, Copy and Paste\u003c/h2\u003e\n\u003cp\u003eFirst, the repetition of the insert mode \u003ccode\u003e\u0026lt;C-r\u0026gt;{register}\u003c/code\u003e command later\nin the book was something I found useful.  I think that\u0026rsquo;s a pretty handy\nway to paste the contents of a register.\nI never knew that \u003ccode\u003e\u0026quot;+\u003c/code\u003e let\u0026rsquo;s you access the system clipboard\neither.  If you put the two together, you can quickly paste from the system\nclipboard without leaving insert mode with \u003ccode\u003e\u0026lt;C-r\u0026gt;+\u003c/code\u003e.  The fact that yank\nstores a copy of what it copies in the \u003ccode\u003e0\u003c/code\u003e register is pretty handy too.\nNice to have an alternate way to access the last yank if I\u0026rsquo;ve clobbered it.\u003c/p\u003e","title":"Practical Vim, 2nd Edition - Second Half"},{"content":"Practical Vim is an excellent resource for tips and trick for using vim. It focuses on core vim features, and doesn\u0026rsquo;t spend any room talking about plugins. Aside from a few hints to how .vimrc settings might affect certain commands, it doesn\u0026rsquo;t spend any time telling you what to put in your .vimrc. It does have an appendix about vimrc settings, in case you need some new ones. The book is laid out as a series of 123 mostly standalone tips, although they do follow a procession of least to most difficult within their respective section. The tips are split between 20 sections. The book doesn\u0026rsquo;t attempt to go into Vimscript. Overall, I found it a useful collection of mostly non-obvious tips for using vim, and I feel like it has made me more capable in using my editor of choice.\nThe author recommends skipping around rather than reading the book from beginning to end, however, I still found the book quite readable. The tips vary in difficulty from very basic (Ex: Tip 47 is \u0026ldquo;Keep Your Fingers on the Home Row\u0026rdquo; and covers h, j, k, and l) to fairly advanced (Ex: Edit the Contents of a Macro). I really enjoy the way the author doesn\u0026rsquo;t repeat any content readily available in the manual. In the electronic copy, he links any manual references to a website with the vim manual. For people reading along, he provides the proper keyword to use with :h in order to lookup the topic via vim help. This allows him to not spend a lot of time on prerequisite info and get directly to useful tips.\nSome tidbits that I\u0026rsquo;ve found useful so far are the keystrokes that he mentions being available in Insert mode. I never paid attention to the fact that you can use \u0026lt;C-w\u0026gt; to delete back one word without leaving insert mode, \u0026lt;C-r\u0026gt;{register} to quickly paste the contents of a register, and \u0026lt;C-v\u0026gt;u{1234} to insert unicode character #1234, all without leaving insert mode. In both the previous examples, the selection in curly brackets is replaced with just a register or just a four digit number, the curly brackets are not typed literally. I generally like hitting my keys one at a time while in vim, but those are a couple of useful chords to use in insert mode. I\u0026rsquo;m not sure I\u0026rsquo;ll use the unicode one often enough to remember it, but the other two are pretty easy to remember and of general use. There is no tip like \u0026ldquo;Here are some keystrokes for Insert mode.\u0026rdquo; but the author instead worked providing these keystrokes into the explanation of how to do something. The \u0026lt;C-r\u0026gt;{register} keystroke was provided in the \u0026ldquo;Paste from a Register Without Leaving Insert Mode\u0026rdquo; tip which focused on it and \u0026lt;C-v\u0026gt;u{1234} was from the \u0026ldquo;Insert Unusual Characters by Character Code\u0026rdquo; tip, but the \u0026lt;C-w\u0026gt; keystroke was provided in the more general \u0026ldquo;Make Corrections Instantly from Insert Mode\u0026rdquo; tip.\nI learned a lot that I didn\u0026rsquo;t know before in the section on Command-Line Mode. As the author puts it, \u0026ldquo;Ex commands strike far and wide.\u0026rdquo; I was unaware of how the range worked with ex commands and of the variety of ex commands available. There are commands to delete, yank, put, copy, move, join, normal (execute Normal mode commands on a specified or range of lines), substitute, and global (execute and ex command where a pattern matches). I\u0026rsquo;ve used substitute a decent bit, but never remember knowing about the others and how you can make them all work flexibly with a range without having to move the cursor there first. It\u0026rsquo;s especially convenient that you can use V to switch into visual line mode and select some lines, then it will prepopulate the range of lines into your : for executing an ex command. You can also use % to target the whole file with a command, which is how I\u0026rsquo;m accustomed to working with substitute. As an example, :%normal A; will append a semicolon to every line in a file or %normal i// will comment out every line in a file given a language where // starts comments. You can even write a script of ex commands and load it into vim with :source {filename}.\nI also learned that in you can use :edit %:h to load the working directory of the currently active buffer as a parameter to edit, and then tab complete it to the name of another file in the same directory. The book recommends you alias %% to %:h since this is so handy. That remap made it into my vimrc. You can even open a file in a nonexistant directory and then use :!mkdir -p %:h to create the directory so you can save the file.\nThe only obvious problem I had with some of the content is that some of it (like the ex commands) is too vim specific to work with vim emulators. Anymore, I spend a lot more time using IdeaVIM in IntelliJ than I clock with real vim, but that\u0026rsquo;s largely a personal problem. The author doesn\u0026rsquo;t avoid forward references, which is only a problem if you\u0026rsquo;re trying to read the book through rather than skip around as recommended. Also, the author sometimes punts further explanation to VimCasts. VimCasts is an excellent resource, and the author of this book is the man behind the site, but I like having explanations in the book I bought rather than having to look to outside video for them. In his defense, he only does it for some of the more graphical tasks like splitting windows and such. Also, around midway through the book when it gets to motion keys, it feels like backtracking to such simple topics to have a Tip 47 that covers h, j, k, and l keys and keeping your hands on home row. This leads to a number of other rather simplistic motion tips that are not new to anyone that\u0026rsquo;s used vim very long. Fortunately these are all kept to one chapter, Chapter 8. The fact that these complaints are all pretty nitpicky goes to show that overall, I didn\u0026rsquo;t find many problems with this book.\nIn general, I especially enjoy how the author explains his thinking behind the use of certain commands. He\u0026rsquo;ll sometimes show how to do something in multiple ways that use the same number of keystrokes, and then explain why one way better fits the general vim mindset (which often means its better for re-use via the . command). He does a lot of this early on in the book, but the tips later in the book he tends to show the one way to perform an operation.\nI\u0026rsquo;m only halfway through the book now, but this post is getting long enough. I\u0026rsquo;ll go ahead and post what I\u0026rsquo;ve written about the first half of the book, and add another post later if I find some awesome tips worth mentioning in the latter half of this book.\nSecond Half\n","permalink":"http://llcawthorne.github.io/posts/practical-vim-1/","summary":"\u003cp\u003ePractical Vim is an excellent resource for tips and trick for using vim.\nIt focuses on core vim features, and doesn\u0026rsquo;t spend any room talking about\nplugins.  Aside from a few hints to how .vimrc settings might affect certain\ncommands, it doesn\u0026rsquo;t spend any time telling you what to put in your .vimrc.\nIt does have an appendix about vimrc settings, in case you need some new ones.\nThe book is laid out as a series of 123 mostly standalone tips, although\nthey do follow a procession of least to most difficult within their\nrespective section.  The tips are split between 20 sections.  The book\ndoesn\u0026rsquo;t attempt to go into Vimscript.  Overall, I found it a useful collection\nof mostly non-obvious tips for using vim, and I feel like it has made me\nmore capable in using my editor of choice.\u003c/p\u003e","title":"Practical Vim, 2nd Edition - First Half"},{"content":"Well, I promised I would review Command Line Power User the other day when I did the Mastering Markdown video, so here it is. This is probably a better video series to give me an opinion of his teaching skills, since it isn\u0026rsquo;t something I know entirely and is actually a little over an hour of video. Each video is longer also, so it probably won\u0026rsquo;t annoy me so much when the video player scrolls down to where I can\u0026rsquo;t see the video after switching files.\nThe first video is seven minutes of basics that are really basic. He advised it was skippable, and I should have taken his advice. He recommends installing iTerm 2 in OS X, which is what I use already on my Macbook. He recommends cygwin for Windows, but I tend to prefer babun on Windows. I\u0026rsquo;m watching these on the Macbook anyway. He recommends installing zshell and oh-my-zsh, which I already use and enjoy. So we\u0026rsquo;re about to where I learn some stuff.\nThe fifth video is about colors. It has some annoying flicking going on. Fortunately that went away. I was wrong about when I would learn something. He\u0026rsquo;s just focusing on how to edit your zshrc in video six. Ooo, in video seven I learned you can CMD+click links in terminal to open them in browser; that\u0026rsquo;s new. Being able to use take to make a directory and create it at the same time is new to me also. Next video is covering command history, which is a pretty standard zshell feature. At least it\u0026rsquo;s short.\nVideo nine is about zsh plugins. I never remember to use my plugins often enough, but I have a lot enabled. I didn\u0026rsquo;t like most of the plugins he showed off, but it\u0026rsquo;s useful to get people thinking about looking at the plugins to find something they\u0026rsquo;ll find useful. It reminds me to lookup commands of some of the ones I have installed. Video ten is about z, which is unrelated to zshell and completely new to me. It\u0026rsquo;s pretty cool. It tracks frequently and recently used directories and lets you switch to them via z regex where regex is a partial match for the directory name. It will switch across multiple directories with the one command easily. I see from the video that I could\u0026rsquo;ve installed it via homebrew rather than by hand, but it\u0026rsquo;s already installed manually now. It has some handy options that are covered in the manpage. The final tip is about trash, which is like rm, but it puts what is deleted in your Trash. I think I\u0026rsquo;m accustomed enough to rm not to worry about that, but those might be words I regret someday.\nOverall, I think there was a lot of useful stuff if you aren\u0026rsquo;t already familiar with zshell and oh-my-zsh. It was a little long for the little bit that I got out of it, but I picked up a couple of useful tips. Overall, his teaching style is reasonable. I didn\u0026rsquo;t feel like falling asleep during either of his videos, and he doesn\u0026rsquo;t come off like he\u0026rsquo;s just directly reading from notes or anything. I might try the JavaScript 30 series when I\u0026rsquo;m in the mood to code some JS, since it\u0026rsquo;s free also. It should be a bit more substantial. Hopefully it doesn\u0026rsquo;t start out as slow.\n","permalink":"http://llcawthorne.github.io/posts/command-line-power-user/","summary":"\u003cp\u003eWell, I promised I would review\n\u003ca href=\"http://www.commandlinepoweruser.com/\"\u003eCommand Line Power User\u003c/a\u003e\nthe other day when I did the\n\u003ca href=\"http://www.masteringmarkdown.com/\"\u003eMastering Markdown\u003c/a\u003e video, so here it\nis.  This is probably a better video series to give me an opinion of his\nteaching skills, since it isn\u0026rsquo;t something I know entirely and is actually\na little over an hour of video.  Each video is longer also, so it probably\nwon\u0026rsquo;t annoy me so much when the video player scrolls down to where I can\u0026rsquo;t\nsee the video after switching files.\u003c/p\u003e","title":"Command Line Power User"},{"content":"First I\u0026rsquo;ld like to say sorry the images are a little big. Not used to screencaps on this retina Macbook.\nSo, I fixed my mistake from last time. I had originally installed ruby via homebrew, but now that I\u0026rsquo;ve read up on rbenv, it seems a lot nicer than the old rvm, and I might want multiple versions of Ruby on my home PC. So I uninstalled Ruby 2.4 and went with brew install rbenv and then used it to install the latest Ruby. I see why the book authors prefer it over RVM now. It\u0026rsquo;s a lot less invasive than the old RVM.\nAnyway, on with Chapter 2, \u0026ldquo;Instant Gratification\u0026rdquo;. I went ahead and completed the code for this chapter and the exercises. Both were fairly trivial. I checked it in at demo51. If you clone that and run bin/rails server from the directory, you\u0026rsquo;re greeted by the site at http://localhost:3000/. You get a lot for very little with Rails. The site you get just from running rails new demo51 looks like this:\nIt also looks like the default server has changed from WEBrick to Puma now. But a page with a picture isn\u0026rsquo;t all that impressive. I must say that I find it pleasant how fast the server starts. I\u0026rsquo;ve become used to my Java EE servers with multiple minute startup times before you can see changes, but not only does this server start fast, it loads changes on the fly when in development mode, so you seldom have to restart it. What is also impressive is how easy it is to modify with a new route. What is slightly intimidating is that the rails new command actually generated forty-six files spread across thirty-four directories. The nice thing is that everything is in its proper place, and hopefully by reading this book and working with the applications a bit more we\u0026rsquo;ll come to understand the logic behind it.\nThe whole application in this chapter is a Hello World modified with a timestamp to show something dynamic. To do this, we need to generate a new controller. Going to the directory of our app and running bin/rails generate controller Say hello goodbye will generate a controller named Say with methods (in Rails terms, these controller methods are called actions) hello and goodbye that will respond to requests to /say/hello and /say/goodbye. It puts the say controller in demo51/app/controllers/say_controller.rb. This is the controller that contains methods for all the /say/ routes. Its starting code that was generated is simply:\nclass SayController \u0026lt; ApplicationController def hello end def goodbye end end Those methods obviously don\u0026rsquo;t do much. Because it inherits from ApplicationController, our SayController automatically gets all the default controller behavior. Even though the controller methods don\u0026rsquo;t have any logic, they still return a site when you navigate to the URL, because by convention they are associated with certain views.\nThe route informs of the file it is currently serving app/views/say/hello.html.erb, which was also automatically generated when we created our controller with the command above. If we edit the file it points us to, we find what looks like a normal html file body:\n\u0026lt;h1\u0026gt;Say#hello\u0026lt;/h1\u0026gt; \u0026lt;p\u0026gt;Find me in app/views/say/hello.html.erb\u0026lt;/p\u0026gt; This is the view that was generated by our command. The views for the SayController we created by default are placed in the app/views/say directory, and there is a view for each of the hello and goodbye methods. The book has us change this view to instead say:\n\u0026lt;h1\u0026gt;Hello from Rails!\u0026lt;/h1\u0026gt; If we refresh our browser window (without restarting the server), we see the new output:\nSo far, we\u0026rsquo;ve learned the place two things go. Controllers go in app/controllers and views go in app/views. The book shows it with the diagram:\nThe book goes on to add the time display to the page directly, then refactor it to have the time generated by the controller and displayed in the view. We\u0026rsquo;ll just skip to that. We modify say_controller.rb to generate the time:\nclass SayController \u0026lt; ApplicationController def hello @time = Time.now end def goodbye end end and modify the view to display the variable set for it by the controller:\n\u0026lt;h1\u0026gt;Hello from Rails!\u0026lt;/h1\u0026gt; \u0026lt;p\u0026gt; It is now \u0026lt;%= @time %\u0026gt; \u0026lt;/p\u0026gt; The time is data, so it is supplied to the view by the controller. The book forewarns us we\u0026rsquo;ll see a lot more of this once we introduce models. It goes on to explain the step-by-step process of what the server goes through when responding to a request, at a very high level. We then customize our goodbye page, but you can checkout the git repo if you want to see that or the results of completing either of the chapter\u0026rsquo;s two exercises. The one remaining item of interest it does in the app is add a link from the Hello page to the Goodbye page and vice versa. It does this using built in helper methods rather than hardcoding URL\u0026rsquo;s. The new hello.html.erb looks like:\n\u0026lt;h1\u0026gt;Hello from Rails!\u0026lt;/h1\u0026gt; \u0026lt;p\u0026gt; It is now \u0026lt;%= @time %\u0026gt; \u0026lt;/p\u0026gt; \u0026lt;p\u0026gt; Time to say \u0026lt;%= link_to \u0026#34;Goodbye\u0026#34;, say_goodbye_path %\u0026gt;! \u0026lt;/p\u0026gt; The first parameter in the call to link_to() is the text to be displayed in the hyperlink, and the next parameter tells Rails to generate the link to the goodbye action of the say controller.\nFinally in this chapter, they display what happens when things break. As the authors put it \u0026ldquo;the true test of the developer friendliness of a framework is how it responds when things go wrong.\u0026rdquo; First, they ask what would happen if we misspelled Time.now as Time.know in our controller. Rails not only tells you the exact spot of the error, it also asks if you meant to type \u0026ldquo;now\u0026rdquo; and offers an interactive debugging console:\nAnd before you start worrying, the web console is only shown if your on the same machine as the web server and running in development mode, so there shouldn\u0026rsquo;t be any chance of anyone getting into it in production unless you specifically whitelist more ips and run the server in development mode. Likewise, if you attempt to go to http://localhost:3000/say/h3llo instead of /say/hello, you get:\nIt gives you a list of possible routes along with what controller and action they are associated with and a helpful search box to trim it down.\nAltogether, the app presented here is totally trivial, but in this chapter they did manage to cover:\nHow to create a new Rails application and how to create a new controller in that application How to create dynamic content in the controller and display it via the view How to link pages together How to debug problems in code or the URL Looks like the next chapter covers a bit of MVC theory, and chapter 4 is a Rails review. I\u0026rsquo;ll probably comment on both in one quick post. Then in Chapter 5, we dig into building a bigger application.\n","permalink":"http://llcawthorne.github.io/posts/awdwr51-02-instant-gratification/","summary":"\u003cp\u003eFirst I\u0026rsquo;ld like to say sorry the images are a little big.  Not used to\nscreencaps on this retina Macbook.\u003c/p\u003e\n\u003cp\u003eSo, I fixed my mistake from last time.  I had originally installed ruby via\nhomebrew, but now that I\u0026rsquo;ve read up on rbenv, it seems a lot nicer than the\nold rvm, and I might want multiple versions of Ruby on my home PC.  So I\nuninstalled Ruby 2.4 and went with \u003ccode\u003ebrew install rbenv\u003c/code\u003e and then used\nit to install the latest Ruby.  I see why the book authors prefer it over\nRVM now.  It\u0026rsquo;s a lot less invasive than the old RVM.\u003c/p\u003e","title":"AWDWR 5.1 - 02 - Instant Gratification"},{"content":"Well, for something a little different, I decided to write my opinion of a free video course. Since I\u0026rsquo;m writing my blog in markdown, I figured why not review it with something other than the Kramdown cheatsheet. Wes Bos has a number of video courses, some free and some paid for. His Mastering Markdown course is one of the free ones. It\u0026rsquo;s really only a single 23 minute video, so not much of a course, but since he just came out with a Learn Node course and has another longer free course of Javascript projects, I figured why not try the little course to get a feel for his teaching style and see if I want to invest any more time and/or money in more of his courses later. His other free courses if your interested include Command Line Power User which has some Z shell tips that I might check out, since I\u0026rsquo;m sure I\u0026rsquo;m not making the most of it, and JavaScript 30 which is 30 days of building 30 things in vanilla JS (which promises no frameworks, no compilers, no libraries, and no boilerplate). Unless this one is terribly, I\u0026rsquo;ll probably sit through the command line one after this. The JavaScript 30 one I\u0026rsquo;ll only invest time in if I like these two. Well, without further ado, here\u0026rsquo;s my opinion of Mastering Markdown.\nGood to see that he isn\u0026rsquo;t opinionated about editors. He says use whatever editor your most comfortable with, even vim. He uses Sublime Text though and recommends a package for it, if you use it. I went ahead and installed it in my copy of Sublime Text. It\u0026rsquo;s called MarkdownEditing and has a lot more features than the built in Sublime Markdown package. I spent almost as much time reading the Package Control Messages as the runtime of these videos, but oh well, sometimes I open stuff up in Sublime, so I might as well get it working alright. I took this chance to toggle some settings in vim-markdown while I was thinking about it.\nIt\u0026rsquo;s a little annoying that his video player jumps down to the video list when it advances videos. Each one, I have to scroll back up after it advances to see the video again. Probably wouldn\u0026rsquo;t be so bad on my big monitor instead of the laptop screen. It\u0026rsquo;s made even more annoying by how short the videos are. Video quality is good, and it is nice that it saves the fact that I\u0026rsquo;ve set the speed up to 1.25 when it switches videos. I learned something about footnote links that I had forgotten, and a cool feature that lets you highlight a code block as a diff, so it wasn\u0026rsquo;t time wasted. He talks a little fast anyway, so I probably wouldn\u0026rsquo;t need the speed increase for something that I didn\u0026rsquo;t already know.\nOverall, I thought the video was OK. I\u0026rsquo;ll try the Command Line Power User course too and see what I think of it. Currently I just use zshell with oh-my-zsh and a couple of plugins enabled, so maybe I can learn some more zshell tricks.\n","permalink":"http://llcawthorne.github.io/posts/mastering-markdown/","summary":"\u003cp\u003eWell, for something a little different, I decided to write my opinion of a\nfree video course.  Since I\u0026rsquo;m writing my blog in markdown, I figured why\nnot review it with something other than the Kramdown cheatsheet.\n\u003ca href=\"http://wesbos.com/\"\u003eWes Bos\u003c/a\u003e\nhas a number of video courses, some free and some paid for.  His\n\u003ca href=\"https://masteringmarkdown.com/\"\u003eMastering Markdown\u003c/a\u003e course is one of the free\nones.  It\u0026rsquo;s really only a single 23 minute video, so not much of a course, but\nsince he just came out with a Learn Node course and has another longer free\ncourse of Javascript projects, I figured why not try the little course to get\na feel for his teaching style and see if I want to invest any more time\nand/or money in more of\nhis courses later.  His other free courses if your interested include\n\u003ca href=\"https://commandlinepoweruser.com/\"\u003eCommand Line Power User\u003c/a\u003e which has some\nZ shell tips that I might check out, since I\u0026rsquo;m sure I\u0026rsquo;m not making the most\nof it, and \u003ca href=\"https://javascript30.com/\"\u003eJavaScript 30\u003c/a\u003e\nwhich is 30 days of building\n30 things in vanilla JS (which promises no frameworks, no compilers, no\nlibraries, and no boilerplate).  Unless this one is terribly, I\u0026rsquo;ll probably\nsit through the command line one after this.  The JavaScript 30 one I\u0026rsquo;ll\nonly invest time in if I like these two.  Well, without further ado, here\u0026rsquo;s\nmy opinion of \u003ca href=\"https://masteringmarkdown.com/\"\u003eMastering Markdown\u003c/a\u003e.\u003c/p\u003e","title":"Mastering Markdown"},{"content":"So, what do I have to blog about? I\u0026rsquo;m always trying out new stuff and reading books, so I figure I\u0026rsquo;ll talk about that. I happen to have just gotten a beta copy of Agile Web Development with Rails 5.1 and since my Ruby and Rails experience from my résumé is a little rusty, I figure I\u0026rsquo;ll read that and blog about the experience. Starting this site using Jekyll has made me think about Ruby lately anyway. It\u0026rsquo;s been many years since I\u0026rsquo;ve read \u0026ldquo;Agile Web Development with Rails\u0026rdquo;, and I think it was the version that covered Rails 1.2, so this should be a pretty new experience for me; both a great refresher and an introduction to what is new in the Rails world these days.\nThe obvious question is why rails when I could play with the hot new Javascript framework. Well, I\u0026rsquo;ve played with React some, along with Ember, and Angular. I might go back to messing with them and blog about the results later. Right now, I\u0026rsquo;m just in a Ruby/Rails mood. I\u0026rsquo;ve always liked how the Ruby community seems to emphasize good programming practices that carry over to any language you work in, and I recall the Agile Web Development book being a good source of sound programming advice. As a side note, I understand that the book now includes information on doing a Javascript front-end with a Rails backend, so I\u0026rsquo;ll get in some Javascript before I\u0026rsquo;m through.\nThe introduction is well paced. The parts I feel worth mentioning are it\u0026rsquo;s argument that \u0026ldquo;Rails Simply Feels Right\u0026rdquo;, which I am inclined to agree with. I\u0026rsquo;ve always thought of Rails as the cadillac of web frameworks. There\u0026rsquo;s a lot of ways to do the same old CRUD in other frameworks, it\u0026rsquo;s just rails has polish and a certain thoughtfulness of layout that makes it all click. It achieves a level of conciseness thanks to \u0026ldquo;Convention over configuration\u0026rdquo;, adhering to the philosophy of DRY (Don\u0026rsquo;t Repeat Yourself), and the natural conciseness of the Ruby programming language (a trait that I miss a lot now in my job, where my Java code tends to include a lot of boiler plate by necessity).\nThe introduction shares a link to the guiding philosophy of Rails, the Rails Doctrine. It can be argued that the Rails Doctrine is what makes Rails continue to be a strong choice as a web framework, even though it\u0026rsquo;s no longer the new darling on the block, and as an aside is also one of the reasons I favor Ember of the Javascript frameworks, since the Ember community were obviously heavily influenced by the Ruby/Rails community. The number one item on the Rails Doctrine is \u0026ldquo;Optimize for programmer happiness\u0026rdquo;. This is lifted straight from Ruby, but is still something that many languages don\u0026rsquo;t put among the considerations, much less as a guiding principle. I forgive them for taking a shot at one of my other favorite language mottos, Python\u0026rsquo;s \u0026ldquo;one and preferably only one way to do something\u0026rdquo;, which I also believe has it\u0026rsquo;s place. But I get their meaning that having a choice of ways to express a solution and being able to choose among them adds a certain bit of artistry to the craft of programming.\nI really appreciate the 2nd principle of the Rails doctrine, \u0026ldquo;Convention over Configuration\u0026rdquo;. Right now, my primary day job is working on an app that\u0026rsquo;s been around for 15 years, and it seems for every problem encountered the people came up with a way from scratch for how to handle it. There\u0026rsquo;s no conventional way to do anything. But as the author says, \u0026ldquo;Part of the Rails’ mission is to swing its machete at the thick, and ever growing, jungle of recurring decisions that face developers creating information systems for the web.\u0026rdquo; Sane defaults make a lot of things possible with little effort, as is shown by the demo app in the next chapter. Just like the Principle of Least Surprise, it begs the question of \u0026ldquo;Sane (or least surprise) to who?\u0026rdquo;, but in general the framework itself is built with enough consistency that once your steeped in its general way of doing things, they make sense as a whole. I endorse the idea that freedom from choice is sometimes exactly what is needed, rather than freedom of choice to do it a different way. \u0026ldquo;A place for everything and everything in its place. Constraints liberate even the most able minds.\u0026rdquo; This is the same type of consistency that Python\u0026rsquo;s motto helps provide, but with some wiggle room left for expression in implementation.\nI could go on analyzing tenets of the Rails Doctrine, but let\u0026rsquo;s get back to the book. I will argue that I sometimes feel \u0026ldquo;monkey patching\u0026rdquo; is more power than programmers need, even if it allows some cool tricks. But I haven\u0026rsquo;t used it much. It just seems a nightmare that you might end up having to look at someone\u0026rsquo;s legacy code down the line where they completely misused it and nothing makes sense. But then again, I like having sharp knives in my kitchen too. I just don\u0026rsquo;t have to cook after many other chefs. Even good programmers sometimes make questionable decisions when pushed for time assuming the language allows certain shortcuts. It\u0026rsquo;s the sharp knives offered by Ruby and Rails that sometimes make me want to stick to the easy consistency of Python and Django, even if they require a little more boilerplate to accomplish similar tasks.\nI did promise to get back to the book. It points out also that \u0026ldquo;Rails is Agile\u0026rdquo;. It\u0026rsquo;s too easy to forget the core tenets of Agile development; they become easily lost to a focus on the ceremonies of Agile. The book restates the four preferences of the Agile Manifesto:\nIndividuals and interactions over processes and tools Working software over comprehensive documentation Customer collaboration over contract negotiation Responding to change over following a plan As someone who works at an organization that is permanently mid-transition between doing things waterfall and approaching them with more agility, I like to remember the core philosophy of the Agile Manifesto and ask if the particular procedure we\u0026rsquo;re seeking to follow embodies those ideas. It\u0026rsquo;s too easy for the core ideas to get lost in the ceremony of scrums and sprint planning meetings and the artifacts of burndown charts.\nWho is this book for? It\u0026rsquo;s aimed at application programmers who want to build and deploy web based applications. It\u0026rsquo;s fine if your new to Rails, and it might be fine even if your new to Ruby. My Ruby is rusty enough that I had to review at Learn X in Y Minutes, but that\u0026rsquo;s a good sign I should be alright. I have a whole catalog of Exercism problems that I worked in Ruby to review with too, in the worst case. This book is more about how to get things done, and doesn\u0026rsquo;t attempt to act as a detailed reference book. There\u0026rsquo;s online API references for that type of stuff.\nThat was just the introduction! We\u0026rsquo;ll be a bit quicker now. Especially since the first chapter is all about getting setup. It has useful instructions for a variety of platforms, including working from a vagrant box or using the cloud9 online IDE. I figure that I like having a recent version of ruby around at the command line anyway, so I followed the OS X instructions and used homebrew (which I already had installed). I\u0026rsquo;m tempted to try Cloud9 sometime, especially since a quick Google tells me that it does have Vim keybindings. Maybe some other time. It looks like in addition to rails, we need yarn and chromedriver. I don\u0026rsquo;t have yarn installed yet, as I\u0026rsquo;ve just used npm for packages, and I\u0026rsquo;m looking forward to using chromedriver from Ruby. I use selenium and chromedriver at work to do end-to-end testing of some of my applications, so I\u0026rsquo;m used to working with chromedriver in Java. I needed to uninstall rvm to get the new version of ruby on my OS X box. It seems that rbenv is the book\u0026rsquo;s preferred way for managing multiple Ruby\u0026rsquo;s these days.\nOn an unrelated note, when did OS X get the ability to remap Caps Lock to Escape without addons? I always used to use Seil and Karbiner, but they quit working in the latest version of OS X. I was about to try Karbiner Elements, but when I checked modifier keys under Keyboard in System Preferences, I saw that it had Caps Lock there and an Escape option. Sorry to toss this in the middle of everything else, but it\u0026rsquo;s really been bugging me in Vim to not have my Caps Lock act as Escape. Unless I stay on a Ruby kick, the next book I review might be Practical Vim. I believe I saw the second edition was on Safari Books the other day. Sorry for the aside, but I got distracted while waiting for homebrew to update all my packages.\nBack to the book. After covering installing in the environment of your choice, along with some advice for when/if things go wrong, we get to Chapter 2, \u0026ldquo;Instant Gratification\u0026rdquo;. In this chapter, we\u0026rsquo;ll make a quick demo app to get our feet wet with Rails. I\u0026rsquo;ve put the demo app with completed exercises up at demo51. I\u0026rsquo;ll cover Chapter 2 next blogpost, this one is already getting pretty large.\n","permalink":"http://llcawthorne.github.io/posts/awdwr51-01-introduction/","summary":"\u003cp\u003eSo, what do I have to blog about?  I\u0026rsquo;m always trying out new stuff and reading\nbooks, so I figure I\u0026rsquo;ll talk about that.  I happen to have just gotten a\nbeta copy of\n\u003ca href=\"https://pragprog.com/book/rails51/agile-web-development-with-rails-5-1\"\u003eAgile Web Development with Rails 5.1\u003c/a\u003e\nand since my Ruby and Rails\nexperience from my résumé is a little rusty, I figure I\u0026rsquo;ll\nread that and blog about the experience.  Starting this site using Jekyll\nhas made me think about Ruby lately anyway.  It\u0026rsquo;s been many years since I\u0026rsquo;ve\nread \u0026ldquo;Agile Web Development with Rails\u0026rdquo;, and I think it was the version that\ncovered Rails 1.2, so this should be a pretty new experience for me; both a\ngreat refresher and an introduction to what is new in the Rails world these\ndays.\u003c/p\u003e","title":"AWDWR 5.1 - 01 - Introduction"},{"content":"Finally got around to putting something together for my github.io site other than what the generator spit out. I went ahead and took advantage of the fact that they let you layout your site with Jekyll to play with some \u0026ldquo;new to me\u0026rdquo; tech. I can write up the posts in Markdown, so maybe it will be easy enough that I actually start blogging here.\n","permalink":"http://llcawthorne.github.io/posts/first-post/","summary":"\u003cp\u003eFinally got around to putting something together for my github.io site other\nthan what the generator spit out.  I went ahead and took advantage of the fact\nthat they let you layout your site with \u003ca href=\"http://jekyllrb.com\"\u003eJekyll\u003c/a\u003e to play\nwith some \u0026ldquo;new to me\u0026rdquo; tech.  I can write up the posts in Markdown, so maybe it\nwill be easy enough that I actually start blogging here.\u003c/p\u003e","title":"Lewis Cawthorne Launches Site"}]