582 Matching Annotations
  1. Dec 2020
  2. Nov 2020
  3. Oct 2020
    1. However, if perform was creating threads and you ended up with closures inside perform, then you could end up with several threads referencing the same local variables captured through the closures. So you do have to be careful about scope issues when you create threads but you don't have to worry about it when dealing with simple methods that only work with local variables

      Однако, если выполнение создавало потоки, и вы закончили с замыканиями внутри выполнения, тогда вы могли бы получить несколько потоков, ссылающихся на одни и те же локальные переменные, захваченные с помощью замыканий. Таким образом, вы должны быть осторожны с проблемами области при создании потоков, но вам не нужно беспокоиться об этом при работе с простыми методами, которые работают только с локальными переменными.

    2. The local variables, such as your hash, are local to the particular invocation of the surrounding method. If two threads end up calling perform at the same time, then each call will get its own execution context and those won't overlap unless there are shared resources involved: instance variables (@hash), class variables (@@hash), globals ($hash), ... can cause concurrency problems. There's nothing to worry about thread-wise with something simple like your perform.

      Локальные переменные, такие как ваш хэш, являются локальными для конкретного вызова окружающего метода. Если два потока вызывают выполнение одновременно, то каждый вызов получит свой собственный контекст выполнения, и они не будут перекрываться, если не задействованы общие ресурсы: переменные экземпляра (@hash), переменные класса (@@ hash), глобальные переменные. ($ hash), ... может вызвать проблемы параллелизма. Не нужно беспокоиться о потоковой передаче с чем-то простым, например, с вашей работой.

  4. Sep 2020
  5. Aug 2020
  6. Jul 2020
    1. Since Ruby 1.9.2, Time implementation uses a signed 63 bit integer, Bignum or Rational. The integer is a number of nanoseconds since the Epoch which can represent 1823-11-12 to 2116-02-20. When Bignum or Rational is used (before 1823, after 2116, under nanosecond), Time works slower as when integer is used.
    1. Arrays are not sets. Trying to treat them as if they are is an error, and will create subtle problems. What should be the result of the following operations? [1, 1] | [1] [1] | [1, 1] Of course, there are more interesting examples. These two are to get you started. I don't care what the results currently are. I don't care what you think they should be. I can present extremely strong arguments for various answers. For this reason, I believe that #| is an ill-defined concept. Generalizing an ill-defined concept is a world of pain. If you insist on treating objects of one class as if they were members of a different class, there should be bumps in the road to at least warn you that maybe this is a bad idea. I'm not going to argue that we should remove or deprecate #|. I don't think of myself as a fanatic. But encouraging this sort of abuse of the type system just creates problems.
  7. Jun 2020
    1. What would be nice is if JavaScript had a built-in way to do what I can do in Ruby with:

      > I18n.interpolate('Hi, %{name}', name: 'Fred')
      => "Hi, Fred"
      

      But to be fair, I18n comes from i18n library, so JS could just as easily (and I'm sure does) have a library that does the same thing.

      Update: Actually, you can do this in plain Ruby (so why do we even need I18n.interpolate?):

      main > "Hi, %{name}" % {name: 'Fred'}
      => "Hi, Fred"
      
      main > ? String#%
      
      From: string.c (C Method):
      Owner: String
      Visibility: public
      Signature: %(arg1)
      Number of lines: 9
      
      Format---Uses str as a format specification, and returns the result
      of applying it to arg. If the format specification contains more than
      one substitution, then arg must be an Array or Hash
      containing the values to be substituted. See Kernel::sprintf for
      details of the format string.
      
         "%05d" % 123                              #=> "00123"
         "%-5s: %016x" % [ "ID", self.object_id ]  #=> "ID   : 00002b054ec93168"
         "foo = %{foo}" % { :foo => 'bar' }        #=> "foo = bar"
      

      I guess that built-in version is fine for simple cases. You only need to use I18n.translate if you need its more advanced features like I18n.config.missing_interpolation_argument_handler.

  8. May 2020
    1. However, distributing such Ruby apps to inexperienced end users or non-Ruby-programmer end users is problematic. If users have to install Ruby first, or if they have to use RubyGems, they can easily run into problems. Even if they already have Ruby installed, they can still run into problems, e.g. by having the wrong Ruby version installed. The point is, it's a very real problem that could harm your reputation.
    1. Programming languages These will probably expose my ignorance pretty nicely.

      When to use different programming languages (advice from an Amazon employee):

      • Java - enterprise applications
      • C# - Microsoft's spin on Java (useful in the Microsoft's ecosystem)
      • Ruby - when speed is more important then legibility or debugging
      • Python - same as Ruby but also for ML/AI (don't forget to use type hinting to make life a little saner)
      • Go/Rust - fresh web service where latency and performance were more important than community/library support
      • Haskell/Erlang - for very elegant/mathematical functional approach without a lot of business logic
      • Clojure - in situation when you love Lisp (?)
      • Kotlin/Scala - languages compiling to JVM bytecode (preferable over Clojure). Kotlin works with Java and has great IntelliJ support
      • C - classes of applications (operating systems, language design, low-level programming and hardware)
      • C++ - robotics, video games and high frequency trading where the performance gains from no garbage collection make it preferable to Java
      • PHP/Hack - testing server changes without rebuilding. PHP is banned at Amazon due to security reasons, but its successor, Hack, runs a lot of Facebook and Slack's backends
  9. Apr 2020
    1. The method name is generated by replacing spaces with underscores. The result does not need to be a valid Ruby identifier though, the name may contain punctuation characters etc. That's because in Ruby technically any string may be a method name. This may require use of define_method and send calls to function properly, but formally there's little restriction on the name.
    1. This situation usually arises from external constraints not design choices such as my example with Sequel. My point is that assigning a value to a constant is allowed by Ruby in certain scopes and not others. It used to be up to the developer to choose wisely when to perform the assignment. Ruby changed on this. Not for everyone's good.
  10. Mar 2020
  11. Feb 2020
    1. Returns an indication of the number of arguments accepted by a method. Returns a nonnegative integer for methods that take a fixed number of arguments. For Ruby methods that take a variable number of arguments, returns -n-1, where n is the number of required arguments. Keyword arguments will be considered as a single additional argument, that argument being mandatory if any keyword argument is mandatory. For methods written in C, returns -1 if the call takes a variable number of arguments.

      What they fail to mention is that apparently the arity is always -1 if the method is available dynamically (due to respond_to_missing?).

  12. Jan 2020
  13. Dec 2019
  14. Nov 2019
  15. Oct 2019
  16. Sep 2019
  17. Aug 2019
  18. Feb 2019
  19. Jan 2016
  20. Nov 2015
  21. Jul 2015
  22. May 2015
    1. Just to focus on the differences between lambdas and Procs, a lambda acts more like a real method. What does that mean?

      Apparently it means a lambda is less ($@(#$ insane.

    2. When you create your own function to accept procs, the guts need to change a little bit because you'll need to use #call instead of yield inside (because which proc would yield run if you had more than one?).

      Too much special!! Why the special cases? Just so that one can type yield instead of invoking a function and naming the argument?

    3. Use that block of code (now called a Proc) as an input to a function by prepending it with an apersand &

      Oh, Ruby. This is entirely too confusing. Why is the ampersand required to signify that something is passed as a block, especially given that it has a type (Proc)? What does it mean if the ampersand isn't used?