453 Matching Annotations
  1. Last 7 days
    1. Dilemma: Do I use this unofficial library with its really nice idiomatic API or the official library (https://github.com/mailgun/mailgun-ruby) with its inferior API?

      I wish this one was still/better maintained because I'd much rather use this API, like: @mailgun.lists.create "devs@your.mailgun.domain" @mailgun.lists.list @mailgun.lists.find "devs@your.mailgun.domain"

      but it's not maintained, and looks like it doesn't have the word events in the source at all, so it's missing any way to use the Events API. :(

    1. Mash duplicates any sub-Hashes that you add to it and wraps them in a Mash. This allows for infinite chaining of nested Hashes within a Mash without modifying the object(s) that are passed into the Mash. When you subclass Mash, the subclass wraps any sub-Hashes in its own class. This preserves any extensions that you mixed into the Mash subclass and allows them to work within the sub-Hashes, in addition to the main containing Mash.
    2. foo = Foo.new(bar: 'baz') #=> {:bar=>"baz"} qux = { **foo, quux: 'corge' } #=> {:bar=> "baz", :quux=>"corge"} qux.is_a?(Foo) #=> true

      This surprised me.

      I would have expected — since Hash literal notation { } was used — that the resulting type would be Hash, not the type of foo. Strange.

      Is this a good thing... or?


      Also, in my quick test, I didn't find this to be true, so...?

      ``` main > symbol_mash.class => SymbolizedMash

      main > { **symbol_mash }.class => Hash ```

    3. by using symbols as keys, you will be able to use the implicit conversion of a Mash via the #to_hash method to destructure (or splat) the contents of a Mash out to a block

      This doesn't actually seem to be an example of destructure/splat. (When it said "destructure the contents ... out to a block", I was surprised and confused, because splatting is when you splat it into an argument or another hash — never a block.)

      An example of destructure/splat would be more like

      method_that_takes_kwargs(**symbol_mash)

    4. Hashie does not have built-in support for coercing boolean values, since Ruby does not have a built-in boolean type or standard method for coercing to a boolean. You can coerce to booleans using a custom proc.

      I use: ActiveRecord::Type::Boolean.new.cast(value)

    5. Mash is an extended Hash that gives simple pseudo-object functionality that can be built from hashes and easily extended. It is intended to give the user easier access to the objects within the Mash through a property-like syntax, while still retaining all Hash functionality.
    1. A SimpleDelegator instance can take advantage of the fact that SimpleDelegator is a subclass of Delegator to call super to have methods called on the object being delegated to. class SuperArray < SimpleDelegator def [](*args) super + 1 end end SuperArray.new([1])[0] #=> 2
  2. Nov 2022
    1. Until now, we had a lot of code. Although we were using a plugin to help with boilerplate code, ready endpoints, and webpages for sign in/sign up management, a lot of adaptations were necessary. This is when Doorkeeper comes to the rescue. It is not only an OAuth 2 provider for Rails but also a full OAuth 2 suite for Ruby and related frameworks (Sinatra, Devise, MongoDB, support for JWT, and more).
    2. The process used to create an OAuth wrapper client is very simple.
    1. def with_something prepare yield on_success end any return, break or throw would skip the on_success code. Skipping over the on_success code also seems quite reasonable when the block calls break and throw. It may not seem like the obvious behaviour for return, but perhaps it is a safe assumption to make in general to think of return as aborting the method yielding to the block. It might be desirable to discourage the use of return in this way for transactions to keep the code clearer, but that would also affect the use of break which seems like a reasonable way to abort a transaction from within the transaction block.
  3. Oct 2022
    1. def initialize_copy(original_animal) self.age = 0 super end def initialize_dup(original_animal) self.dna = generate_dna self.name = "A new name" super end def initialize_clone(original_animal) self.name = "#{original_animal.name} 2" super end
    1. But this sounds like spreading fear and doubt when the Ruby parser has no such concepts :) {} always binds tightly to the call right next to it. This block {} will never go to using, unless it's rewritten as do ... end.
  4. Sep 2022
    1. Aligning everything with however long the method name is makes every indention different. belongs_to :thing, class_name: 'ThisThing', foreign_key: :this_thing_id has_many :other_things, class_name: 'ThisOtherThing', foreign_key: :this_other_thing_id validates :field, presence: true Compared to the following, which all align nicely on the left. belongs_to :thing, class_name: 'ThisThing', foreign_key: :this_thing_id has_many :other_things, class_name: 'ThisOtherThing', foreign_key: :this_other_thing_id validates :field, presence: true
    1. Also be aware of how Ruby handles aliases and inheritance: an alias references the method that was resolved at the time the alias was defined; it is not dispatched dynamically.
    2. Prefer alias when aliasing methods in lexical class scope as the resolution of self in this context is also lexical, and it communicates clearly to the user that the indirection of your alias will not be altered at runtime or by any subclass unless made explicit.

      reassurance of lack of possibility for run-time shenanigans

  5. Aug 2022
    1. URI::HTTPS.build(host: AUTH0_CONFIG['auth0_domain'], path: '/v2/logout', query: to_query(request_params)).to_s
    2. def to_query(hash) hash.map { |k, v| "#{k}=#{CGI.escape(v)}" unless v.nil? }.reject(&:nil?).join('&') end
    1. You can pass any options to puma via the server setting Capybara.server = :puma, { queue_requests: true }
    2. This very much appears to be a bug or design flaw in puma - The fact that a persistent connection ties up a thread on the chance a request might come over that connection seems like not great behavior. This would really only be an issue when puma is run with no workers (which wouldn't be done in production) but it still seems a little nuts.
  6. Jul 2022
    1. Create a new controller to override the original: app/controllers/active_storage/blobs_controller.rb

      Original comment:

      I've never seen monkey patching done quite like this.

      Usually you can't just "override" a class. You can only reopen it. You can't change its superclass. (If you needed to, you'd have to remove the old constant first.)

      Rails has already defined ActiveStorage::BlobsController!

      I believe the only reason this works:

      class ActiveStorage::BlobsController < ActiveStorage::BaseController

      is because it's reopening the existing class. We don't even need to specify the < Base class. (We can't change it, in any case.)

      They do the same thing here: - https://github.com/ackama/rails-template/pull/284/files#diff-2688f6f31a499b82cb87617d6643a0a5277dc14f35f15535fd27ef80a68da520

      Correction: I guess this doesn't actually monkey patch it. I guess it really does override the original from activestorage gem and prevent it from getting loaded. How does it do that? I'm guessing it's because activestorage relies on autoloading constants, and when the constant ActiveStorage::BlobsController is first encountered/referenced, autoloading looks in paths in a certain order, and finds the version in the app's app/controllers/active_storage/blobs_controller.rb before it ever gets a chance to look in the gem's paths for that same path/file.

      If instead of using autoloading, it had used require_relative (or even require?? but that might have still found the app-defined version earlier in the load path), then it would have loaded the model from activestorage first, and then (possibly) loaded the model from our app, which (probably) would have reopened it, as I originally commented.

    1. meat: https://github.com/musaffa/file_validators/blob/master/lib/file_validators/validators/file_content_type_validator.rb

      Compared to https://github.com/aki77/activestorage-validator, I slightly prefer this because - it has more users and has been battle tested more - is more flexible: can specify exclude as well as allow - has more expansive Readme documentation - is mentioned by https://github.com/thoughtbot/paperclip/blob/master/MIGRATING.md#migrating-from-paperclip-to-activestorage - mentions security: whether or not it's needed, at least this makes extra attempt to be secure by using external tool to check content_type; https://github.com/aki77/activestorage-validator/blob/master/lib/activestorage/validator/blob.rb just uses blob.content_type, which I guess just trusts whatever ActiveStorage gives us (which seems fair too: perhaps this should be kicked up to them to be their concern)

      In fact, it looks like ActiveStorage does do some kind of mime type checking...

      activestorage-6.1.6/app/models/active_storage/blob/identifiable.rb ``` def identify_without_saving unless identified? self.content_type = identify_content_type self.identified = true end end

      def identify_content_type
        Marcel::MimeType.for download_identifiable_chunk, name: filename.to_s, declared_type: content_type
      end
      

      ```

  7. Jun 2022
    1. Symbols are an interesting twist on the idea of a string. The full explanation can be a bit long, but here’s the short version:Strings can be changed, so every time a string is used, Ruby has to store it in memory even if an existing string with the same value already exists. Symbols, on the other hand, are stored in memory only once, making them faster in certain situations.One common application where symbols are preferred over strings are the keys in hashes. We’ll cover this in detail in the hashes lesson later in the course.You won’t need to use symbols much in the beginning, but it’s good to get familiar with what they are and what they look like so that you can recognize them.

      symbols

    1. As a documentation convention, methods are listed out with either a :: or a # to indicate two different kinds of publicly accessible methods. Methods denoted by :: are considered class methods, while methods denoted by # are considered instance methods.

      In documentation (not actual code):

      :: -> class methods

      # -> instance methods

  8. May 2022
    1. before(:all) do @fiber = Fiber.new do Benchmark.ips do |benchmark| @benchmark = benchmark Fiber.yield benchmark.compare! end end @fiber.resume end
    2. does the microgem I published work for your use case?
    3. We actually already use this patch: http://myronmars.to/n/dev-blog/2012/03/building-an-around-hook-using-fibers
    1. I’ve been looking everywhere for examples of how to use Fibers that are complicated enough to do something useful but simple enough to understand. For an older feature it’s one of the least documented.
    2. I haven't done a lot with Fibers,so having you point out a potential use for them and then walk through it was great.
  9. Apr 2022
    1. Caution: + continues the statement but not the string. puts "foo"+"bar".upcase gives you fooBAR, whereas puts ("foo"+"bar").upcase gives you FOOBAR. (Whether or not there's a newline after the +.) But: if you use a backslash instead of the plus sign, it will always give you FOOBAR, because combining lines into one statement, and then combining successive strings into one string, happen before the string method gets called.
    1. It is very important that your gem reopens the modules ActiveJob and ActiveJob::QueueAdapters instead of defining them. Because their proper definition lives in Active Job. Furthermore, if the project reloads, you do not want any of ActiveJob or ActiveJob::QueueAdapters to be reloaded. Bottom line, Zeitwerk should not be managing those namespaces. Active Job owns them and defines them. Your gem needs to reopen them.
    1. export RUBY_THREAD_VM_STACK_SIZE=2000000

      This example is how to make stack size larger, but my use case is actually needing to make it smaller.

      Why? Because I was debugging a bug that was causing a SystemStackError and it took a long time to hit the stack size limit. In order to iterate more quickly (run my test that exercised the problem code), I wanted to set the stack size smaller, so I did:

      export RUBY_THREAD_VM_STACK_SIZE=200

    1. I'm a big fan of refinements (yes, I am), and that's what I did to make this code look simpler and more beautiful:
  10. Mar 2022
    1. # Allows you to just run "pry" inside a Rails app directory and get # everything loaded as rails c does. Inside a Bundler directory does # what bundle console does.
    1. Ruby Object Mapper (rom-rb) is a fast ruby persistence library with the goal of providing powerful object mapping capabilities without limiting the full power of the underlying datastore.
  11. Feb 2022
    1. There are two pairs of methods for sending/receiving messages: Object#send and ::receive for when the sender knows the receiver (push); Ractor.yield and Ractor#take for when the receiver knows the sender (pull);
    1. I am using them in a real life application. I am calculating the available tables for a full calendar with many time slots and with respect to many configurable business rules for restaurants. Using callcc this feature got blazingly fast and very nicely readable. Also we use it to optimise table arrangements with respect to complex restaurant business rules (even something like: Guest A doesn't like to sit near Guest B). Please just have a look at these resources: https://github.com/chikamichi/amb/tree/master/examples http://web.archive.org/web/20151116124853/http://liufengyun.chaos-lab.com/prog/2013/10/23/continuation-in-ruby.html Please help me to keep Guest A away from Guest B. Bad things might happen.
    2. "Context" manipulation is one of big topic and there are many related terminologies (academic, language/implementation specific, promotion terminologies). In fact, there is confusing. In few minutes I remember the following related words and it is good CS exam to describe each :p Thread (Ruby) Green thread (CS terminology) Native thread (CS terminology) Non-preemptive thread (CS terminology) Preemptive thread (CS terminology) Fiber (Ruby/using resume/yield) Fiber (Ruby/using transfer) Fiber (Win32API) Generator (Python/JavaScript) Generator (Ruby) Continuation (CS terminology/Ruby, Scheme, ...) Partial continuation (CS terminology/ functional lang.) Exception handling (many languages) Coroutine (CS terminology/ALGOL) Semi-coroutine (CS terminology) Process (Unix/Ruby) Process (Erlang/Elixir) setjmp/longjmp (C) makecontext/swapcontext (POSIX) Task (...)
  12. Jan 2022
    1. Ruby 2.6 introduces an initial implementation of a JIT (Just-In-Time) compiler. The JIT compiler aims to improve the performance of Ruby programs. Unlike traditional JIT compilers which operate in-process, Ruby’s JIT compiler writes out C code to disk and spawns a common C compiler to generate native code. For more details about it, see the MJIT organization by Vladimir Makarov.
  13. Dec 2021
    1. How to Create a Micro-Job Marketplace Like Fiverr: Features, Cost, TimelineTimurTech JournalistMarketplaceProduct GuideHomeBlogEntrepreneurshipHow to Create a Micro-Job Marketplace Like Fiverr: Features, Cost, TimelinePublishedNov 19, 2021UpdatedNov 19, 202120 min readIt’s no secret that the COVID-19 pandemic has led many people to reconsider their jobs. Now, freelance as an alternative career path steadily becomes a reality. 50.9% of the U.S. workforce will be freelancing by 2027, a Statista survey shows. Businesses like Fiverr and fellow gig-focused companies rode the wave. To be more precise, they adopted a model allowing the hire of independent contractors without any legwork. How do such tools set the new trend in powering freelancers? In this article, we share proven methods geared towards freelance website growth. Moreover, you will get a glimpse of how to create a micro-job marketplace like Fiverr of your own.

      It’s no secret that the COVID-19 pandemic has led many people to reconsider their jobs. Now, freelance as an alternative career path steadily becomes a reality. 50.9% of the U.S. workforce will be freelancing by 2027, a Statista survey shows.

      Businesses like Fiverr and fellow gig-focused companies rode the wave. To be more precise, they adopted a model allowing the hire of independent contractors without any legwork. How do such tools set the new trend in powering freelancers?

      In this article, we share proven methods geared towards freelance website growth. Moreover, you will get a glimpse of how to create a micro-job marketplace like Fiverr of your own.

  14. Nov 2021
    1. How to Choose a Reliable SaaS Application Development CompanyKateCloud & SaaS Product ResearcherDmitryCEOSaaSHomeBlogEntrepreneurshipHow to Choose a Reliable SaaS Application Development CompanyPublishedAug 5, 2020UpdatedAug 5, 202012 min readCurrently, SaaS is the largest segment of the global public cloud services market. The growing SaaS industry provides an equal-opportunity atmosphere for businesses. It concerns enterprises from startups to tech giants – and any size in between. It explains why traditional software companies, like Microsoft and Adobe, decided to look into that direction too. Indeed, the time is ripe for developing a SaaS application now. But however tempting it may be, do not dive in headfirst with launching a SaaS product, because sometimes, it can be very challenging. That is why we have prepared a guide on finding a SaaS application development company that will be your best bet.

      Looking to build a SaaS app? You will need help of a reliable development team. Check our advice on how to choose a SaaS development company.

    1. SaaS Product Development: Why Choose Ruby on Rails Framework?KateCloud & SaaS Product ResearcherRuby/RailsSaaSHomeBlogTechnologySaaS Product Development: Why Choose Ruby on Rails Framework?PublishedSep 10, 2020UpdatedSep 10, 202013 min readWhich technology to pick for your SaaS business to succeed? This question is not uncommon in our days. In fact, quite the opposite because the SaaS model has become a meaningful part of every business domain. And the demand for SaaS product development is higher than ever and still increasing. This article will discuss the essential factors you need to consider when selecting a framework for your SaaS project. Also, we will introduce the top 3 frameworks for building a SaaS product with their pros and cons. Read on to see the best examples of SaaS applications.

      Choosing the right tech stack can help you save costs and make your app stand out in the saturated market. Let’s discuss why Ruby on Rails can be your best choice.

    1. What Makes Ruby on Rails Perfect for Marketplace Development?AlinaE-Commerce & SaaS StrategistMarketplaceRuby/RailsHomeBlogEntrepreneurshipWhat Makes Ruby on Rails Perfect for Marketplace Development?PublishedJul 13, 2020UpdatedJul 13, 202012 min readThe last several years have been marked with the rise of different marketplaces. Airbnb, AliExpress, Etsy, Booking.com are on everyone’s lips. That's not surprising that the idea of launching a second Amazon or eBay seems so appealing. To win the e-commerce race, entrepreneurs focus on providing excellent customer experience and build fast-loading and scalable websites. Besides, business owners take various security measures to protect their customers’ sensitive information. This way, they can gain clients’ trust and boost sales. When building a custom marketplace, what technology stack is best to achieve all these goals? Our answer is simple: Ruby on Rails. In this article, we will fill you in on the Ruby on Rails marketplace development. At Codica, we are passionate fans of this framework and have built numerous e-commerce platforms with its help. Based on our experience, we will discuss the key reasons to choose RoR for building a successful marketplace.

      The last several years have been marked with the rise of different marketplaces. Airbnb, AliExpress, Etsy, Booking.com are on everyone’s lips. That's not surprising that the idea of launching a second Amazon or eBay seems so appealing.

      To win the e-commerce race, entrepreneurs focus on providing excellent customer experience and build fast-loading and scalable websites. Besides, business owners take various security measures to protect their customers’ sensitive information. This way, they can gain clients’ trust and boost sales.

      When building a custom marketplace, what technology stack is best to achieve all these goals? Our answer is simple: Ruby on Rails.

      In this article, we will fill you in on the Ruby on Rails marketplace development. At Codica, we are passionate fans of this framework and have built numerous e-commerce platforms with its help. Based on our experience, we will discuss the key reasons to choose RoR for building a successful marketplace.

  15. Oct 2021
    1. Collapsing directories Say some directories in a project exist for organizational purposes only, and you prefer not to have them as namespaces. For example, the actions subdirectory in the next example is not meant to represent a namespace, it is there only to group all actions related to bookings: booking.rb -> Booking booking/actions/create.rb -> Booking::Create
  16. Sep 2021
    1. Thanks to Rack Middleware and Rails 3 you can output pretty JSON for every request without changing any controller of your app. I have written such middleware snippet and I get nicely printed JSON in browser and curl output.
    1. The important thing to understand is that there is no such thing as a class method in Ruby. A class method is really just a singleton method. There is nothing special about class methods. Every object can have singleton methods. We just call them "class methods" when the object is a Class because "singleton method of an instance of Class" is too long and unwieldy.
    2. Class methods are actually instance methods defined on the singleton class of a class.
  17. Aug 2021
    1. What if I told you there was a way to do this in Ruby?:destructure def adds(a: 1, b: 2) a + bendadds(a: 1, b: 2)# => 3adds(OpenStruct.new(a: 1, b: 2))# => 3Foo = Struct.new(:a, :b)adds(Foo.new(1,2))# => 3
    2. def destructure(method_name) meta_klass = class << self; self end method_proc = method(method_name) unless method_proc.parameters.all? { |t, _| t == :key } raise "Only works with keyword arguments" end arguments = method_proc.parameters.map(&:last) destructure_proc = -> object { values = if object.is_a?(Hash) object else arguments.map { |a| [a, object.public_send(a)] }.to_h end method_proc.call(values) } meta_klass.send(:define_method, method_name, destructure_proc) method_nameend
    1. this kind of run-time code generation is certainly more natural in Ruby, it's one of its Lispish elements
    2. Rubyists don't call these things annotations. One of the things I like doing is to find common techniques that cross languages, for me this is a common technique and 'annotation' seems like a good generic word for it. I don't know if Rubyists will agree.
    1. An internal DSL (often called an Embedded DSL) is a DomainSpecificLanguage that is written inside an existing host language. It's a common way of thinking in a number of programming language communities - particularly the Lisp community. It's now gaining a lot of attention as DSLs are a common way of thinking in the rapidly growing Ruby community.
    1. # And standalone like a case:Qo.match(people.first, Qo.m(age: 10..19) { |person| "#{person.name} is a teen that's #{person.age} years old" }, Qo.m(:*) { |person| "#{person.name} is #{person.age} years old" })
    2. # How about some "right-hand assignment" pattern matchingname_longer_than_three = -> person { person.name.size > 3 }people_with_truncated_names = people.map(&Qo.match_fn( Qo.m(name_longer_than_three) { |person| Person.new(person.name[0..2], person.age) }, Qo.m(:*) # Identity function, catch-all))
    1. 3. The no-keyword-arguments syntax (**nil) is introduced You can use **nil in a method definition to explicitly mark the method accepts no keyword arguments. Calling such methods with keyword arguments will result in an ArgumentError. (This is actually a new feature, not an incompatibility)
    2. This is useful to make it explicit that the method does not accept keyword arguments. Otherwise, the keywords are absorbed in the rest argument in the above example.
    3. If you extend a method to accept keyword arguments, the method may have incompatibility as follows: # If a method accepts rest argument and no `**nil` def foo(*args) p args end # Passing keywords are converted to a Hash object (even in Ruby 3.0) foo(k: 1) #=> [{:k=>1}] # If the method is extended to accept a keyword def foo(*args, mode: false) p args end # The existing call may break foo(k: 1) #=> ArgumentError: unknown keyword k
    4. If your code doesn’t have to run on Ruby 2.6 or older, you may try the new style in Ruby 2.7. In almost all cases, it works. Note that, however, there are unfortunate corner cases as follows:
    5. Ruby 2.6 or before themselves have tons of corner cases in keyword arguments.
    6. You need to explicitly delegate keyword arguments. def foo(*args, **kwargs, &block) target(*args, **kwargs, &block) end
    7. you can use the new delegation syntax (...) that is introduced in Ruby 2.7. def foo(...) target(...) end
    8. ruby2_keywords allows you to run the old style even in Ruby 2.7 and 3.0.
    9. Will my code break on Ruby 2.7? A short answer is “maybe not”. The changes in Ruby 2.7 are designed as a migration path towards 3.0. While in principle, Ruby 2.7 only warns against behaviors that will change in Ruby 3, it includes some incompatible changes we consider to be minor. See the “Other minor changes” section for details. Except for the warnings and minor changes, Ruby 2.7 attempts to keep the compatibility with Ruby 2.6. So, your code will probably work on Ruby 2.7, though it may emit warnings. And by running it on Ruby 2.7, you can check if your code is ready for Ruby 3.0.
    10. However, this style is not recommended in new code, unless you are often passing a Hash as a positional argument, and are also using keyword arguments
  18. Jul 2021
    1. You can do this elegantly with throw/catch, like this:
    2. In most languages, there is no clean equivalent for breaking out of a recursive algorithm that uses a recursive function. In Ruby, though, there is!
    3. it's much faster—the stack frame does not have to be carried along the "thrown symbol", and no object is created. Lightweight nonlinear flow control.
    4. Throw it's a more elegant way to use an exception-like system as a control flow.
  19. Jun 2021
    1. With GraphQL-Ruby, it’s possible to hide parts of your schema from some users. This isn’t exactly part of the GraphQL spec, but it’s roughly within the bounds of the spec.
  20. evilmartians.com evilmartians.com