Hacker Newsnew | past | comments | ask | show | jobs | submit | Rhainur's commentslogin

In my own (admittedly limited) experience, 2 employees in my company (that had no programming knowledge or experience) have vibe coded apps that simplify their daily roles. The apps basically automate a flowchart of steps where multiple people need to submit certain pieces of info and as they do, a "project" moves through stages and the employees get notified on Telegram.

The app really is just several simple forms with some if/else logic, but claude code allowed them to get the app up and running and deployed on vercel's free tier, and it's Good Enough™ to save them an hour or so each day lost in messaging and chasing up things.

I don't think anyone would ever have targeted an app for sale to them, and it would have been hard to twist some sort of flow management app and integrate it with Zapier or something to handle external api calls. With claude code they could just tell it what they wanted and solve their very niche issue. That's why I think that even though LLM coding has improved so much you might not see more software for sale - it's easier for people to just...make their own software.


The best part of this workflow - which I see often - is that by having someone build custom software to automate some process they often step back away from the process being their job. That eventually translates into them understanding that some (or sometimes most or all) of that process is not needed. There are so many corporate processes that were implemented and then become the way... and if there are people who identify that process as being their job those people resist attempts to optimize that process.

I have seem several people use AI to write apps to automate a process and along they way finally ask the question 'do we even need this process?'.

Regrettably this does not happen everywhere.


Don’t get me wrong, :) that’s pretty cool! I’ve also made highly personalized mini apps for my own personal life. Currently working on an iOS one to log mood and correlate it with HealthKit data since the native health app does a bad job of it.

That said, I meant more like production grade apps that have to serve N>1, which is IME where the hard part LLMs suck at comes in. I saw a tweet somewhere along the lines of “CEOs/execs are so divorced from the last mile effort that they are uniquely susceptible to believing AI can replace engineers end to end”


Other people have mentioned "dynamic typing" as being the reason for this, but that's not actually true. The real reason is two Ruby features: `define_method` and `method_missing`.

If you have a class `Customer` with a field `roles` that is an array of strings, you can write code like this

  class Customer
    ROLES = ["superadmin", "admin", "user"]

    ROLES.each do |role|
      define_method("is_#{role}?") do
        roles.include?(role)
      end
    end
  end
In this case, I am dynamically defining 3 methods `is_superadmin?` `is_admin?` and `is_user?`. This code runs when the class is loaded by the Ruby interpreter. If you were just freshly introduced into this codebase, and you saw code using the `is_superadmin?` method, you would have no way of knowing where it's defined by simply grepping. You'd have to really dig into the code - which could be more complicated by the fact that this might not even be happening in the Customer class. It could happen in a module that the Customer class includes/extends.

The other feature is `method_missing`. Here's the same result achieved by using that instead of define_method:

  class Customer
    ROLES = ["superadmin", "admin", "user"]

    def method_missing(method_name, *args)
      if method_name.to_s =~ /^is_(\w+)\?$/ && ROLES.include?($1)
        roles.include?($1)
      else
        super
      end
    end
  end
Now what's happening is that if you try to call a method that isn't explicitly defined using `def` or the other `define_method` approach, then as a last resort before raising an error, Ruby checks "method_missing" - you can write code there to handle the situation.

These 2 features combined with modules are the reason why "Go to Definition" can be so tricky.

Personally, I avoid both define_method and method_missing in my actual code since they're almost never worth the tech debt. I have been developing in Rails happily for 15+ years and only had one or two occasions where I felt they were justified and the best approach, and that code was heavily sprinkled with comments and documentation.


To add, the above code is a pretty near approximation of the literal code inside the devise codebase, which is a very standard Ruby auth system.

See here:

https://github.com/heartcombo/devise/blob/main/lib/devise/co...

        def self.define_helpers(mapping) #:nodoc:
        mapping = mapping.name

        class_eval <<-METHODS, __FILE__, __LINE__ + 1
          def authenticate_#{mapping}!(opts = {})
That code is *literally* calling class_eval with a multi-line string parameter, where it inlines the helper name (like admin, user, whatever), to grow the class at runtime.

It hurts my soul.


It's been widely understood in the Ruby community for some time now that metaprogramming—like in the example above—should generally be limited to framework or library code, and avoided in regular application code.

Dynamically generated methods can provide amazing DX when used appropriately. A classic example from Rails is belongs_to, which dynamically defines methods based on the arguments provided:

class Post < ApplicationRecord belongs_to :user end

This generates methods like:

post.user - retrieves the associated user

post.user=(user) - sets the associated user

post.user_changed? - returns true if the user foreign key has changed.


Aren’t all these enhancement methods that are added dynamically to every ActiveRecord a major reason why regular AR calls are painfully slow and it’s better to use .pluck() instead? One builds a whole object from pieces, the other vomits put an array?


It's simply not true that "regular AR calls are painfully slow." In the context of a web request, the time spent instantiating Active Record objects is negligible. For example, on my laptop:

Customer.limit(1000).to_a

completes in about 10ms, whereas:

Customer.last(1000).pluck(:id, :name, :tenant_id, :owner_id, :created_at, :updated_at)

runs in around 7ms.

Active Record methods are defined at application boot time as part of the class, they're not rebuilt each time an instance is created. So in a typical web app, there's virtually no performance penalty for working with Active Record objects.

And when you do need raw data without object overhead, .pluck and similar methods are available. It’s just a matter of understanding your use case and choosing the right tool for the job.


Thank you both for the time you spent explaining this.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: