330 Matching Annotations
  1. Last 7 days
  2. 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.
  3. 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.
    1. prepend(Module.new do
    2. A lot of projects leveraging CDP appeared since then, including the most well-known one—Puppeteer, a browser automation library for Node.js. What about the Ruby world? Ferrum, a CDP library for Ruby, although being a pretty young one, provides a comparable to Puppeteer experience. And, what’s more important for us, it ships with a companion project called Cuprite—a pure Ruby Capybara driver using CDP.
    1. Same feature in TypeScript¶ It's worth mentioning that other languages have a shortcut for assignment var assignment directly from constructor parameters. So it seems especially painful that Ruby, despite being so beautifully elegant and succinct in other areas, still has no such shortcut for this. One of those other languages (CoffeeScript) is dead now, but TypeScript remains very much alive and allows you to write this (REPL): class Foo { constructor(public a:number, public b:number, private c:number) { } } instead of this boilerplate: class Foo { constructor(a, b, c) { this.a = a; this.b = b; this.c = c; } } (The public/private access modifiers actually disappear in the transpiled JavaScript code because it's only the TypeScript compiler that enforces those access modifiers, and it does so at compile time rather than at run time.) Further reading: https://www.typescriptlang.org/docs/handbook/2/classes.html#parameter-properties https://basarat.gitbook.io/typescript/future-javascript/classes#define-using-constructor https://kendaleiv.com/typescript-constructor-assignment-public-and-private-keywords/ I actually wouldn't mind being able to use public/private modifiers on instance var parameters in Ruby, too, but if we did, I would suggest making that be an additional optional shortcut (for defining accessor methods for those instance vars) that builds on top of the instance var assignment parameter syntax described here. (See more detailed proposal in #__.) Accessors are more of a secondary concern to me: we can already define accessors pretty succinctly with attr_accessor and friends. The bigger pain point that I'm much more interested in having a succinct shortcut for is instance var assignment in constructors. initialize(@a, @b, @c) syntax¶ jsc (Justin Collins) wrote in #note-12: jjyr (Jinyang Jiang) wrote: I am surprised this syntax has been repeatedly requested and rejected since 7 years ago. ... As someone who has been writing Ruby for over 10 years, this syntax is exactly that I would like. I grow really tired of writing def initialize(a, b, c) @a = a @b = b @c = c end This would be perfect: def initialize(@a, @b, @c) end I'm a little bit sad Matz is against this syntax, as it seems so natural to me. Me too!! I've been writing Ruby for over 15 years, and this syntax seems like the most obvious, simple, natural, clear, unsurprising, and Ruby-like. I believe it would be readily understood by any Rubyist without any explanation required. Even if you saw it for the first time, I can't think of any way you could miss or misinterpret its meaning: since @a is in the same position as a local variable a would normally be, it seems abundantly clear that instead of assigning to a local variable, we're just assigning to the variable @a instead and of course you can reference the @a variable in the constructor body, too, exactly the same as you could with a local variable a passed as an argument. A workaround pattern¶ In the meantime, I've taken to defining my constructor and list of public accessors (if any) like this: attr_reader \ :a, :b def new( a, b) @a, @b = a, b end ... which is still horrendously boilerplatey and ugly, and probably most of you will hate — but by lining up the duplicated symbols into a table of columns, I like that I can at least more easily see the ugly duplication and cross-check that I've spelled them all correctly and handled them all consistently. :shrug: Please??¶ Almost every time I write a new class in Ruby, I wish for this feature and wonder if we'll ever get it. Can we please?
    2. I am not sure if this is an improvement. To me it does not seem very pretty. Of course I am biased since I also prefer () in method definitions if they have arguments; although I think it is fine that ruby does not mind omitting the (). For my brain, I like the () for visual separation.
    1. When defining accessors in Ruby, there can be a tension between brevity (which we all love) and best practice.
    2. in languages (like JavaScript and Java) where external objects do have direct access to instance vars
    3. But what's the matter with "raw" instance variables? They are internal to your instance; the only code that will call them by name is code inside pancake.rb which is all yours. The fact that they start with @, which I assume made you say "blech", is what makes them private. Think of @ as shorthand for private if you like.

      I agree / like that: @ is just shorthand for private.

      But OP clarified in a comment that the @ itself is not what they disliked: it was the accessing data directly instead of going through an accessor method.

      The raw variable is the implementation, the accessor is the interface. Should I ignore the interface because I'm internal to the instance?

    4. class << Object def private_accessor(*names) names.each do |name| attr_accessor name private "#{name}=" end end end
    5. Setting an instance variable by going through a setter is good practice, and using two access modifiers is the way to accomplish that for a read-only instance variable
    1. I don't think this warrants adding to the Array class, since it's not generalizable to all the types that Arrays can contain.

      You could say the same thing about Array#sort. It can cause an error if elements of the array aren't all of the same type/shape. Just make sure it's safe to use first, and thenArray#sort, Array#sum, Array#average, ... are all quite handy and useful to have on Array class.

    2. That's not exactly Symbol#to_proc conversion — it's part of the inject interface, mentioned in the documentation. The to_proc operator is &
    3. instance_eval { reduce(:+) / size.to_f }
    4. I don't think it is too clever. I think it solves the problem idiomatically. I.e., it uses reduce, which is exactly correct. Programmers should be encouraged to understand what is correct, why it is correct, and then propagate. For a trivial operation like average, true, one doesn't need to be "clever". But by understanding what "reduce" is for a trivial case, one can then start applying it to much more complex problems. upvote.
    5. Thanks, this was just what I was looking for! This is a perfect appropriate use of instance_eval. I do not understand the nay-sayers. If you already have your array in a variable, then sure, a.reduce(:+) / a.size.to_f is pretty reasonable. But if you want to "in line" find the mean of an array literal or an array that is returned from a function/expression — without duplicating the entire expression ([0,4,8].reduce(:+) / [0,4,8].length.to_f, for example, is abhorrent) or being required to assign to a local, then instance_eval option is a beautiful, elegant, idiomatic solution!!
    6. instance_eval is analogous to using tap, yield_self, … when you are dealing with a chain of method calls: do use it whenever it's appropriate and helpful! And in this case, I absolutely believe that it is.
    7. instance_eval lets you run the code while only specifying a once, so it can be chained with other commands. I.e. random_average = Array.new(10) { rand(10) }.instance_eval { reduce(:+) / size.to_f } instead of random = Array.new(10) { rand(10) }; random_average = random.reduce(:+) / random.size
    8. I don't know, using instance_eval this way just seems weird, and it has a lot of gotchas associated with it that make this approach a bad idea, IMO. (For example, if you tried to access and instance variable or a method on self inside that block, you'd run into problems.) instance_eval is more for metaprogramming or DSL.

      But that's exactly when/why you'd use it: to make self refer to the instance! Just learn that and you'll be fine. You can still access locals from outside the block. And if you need to access instance variables/methods of a different instance, then sure, it's probably a sign you shouldn't be using instance_eval here.

    9. Or if you're looking for a core extension that adds this to the Array class, I'd recommend the facets gem (require 'facets/array/average'). Then you can just do array.average. And, from looking at the source, it turns out they do the exact same thing as the instance_eval approach above. The only difference is that it's implemented as a method—which of course already has self pointing to itself—instead of a block): def average; return nil if empty?; reduce(:+) / length.to_f; end Main advantage of this is that it's even more concise/readable and it handles the empty? case.
  4. May 2021
    1. Because constants in Ruby aren't meant to be changed, Ruby discourages you from assigning to them in parts of code which might get executed more than once, such as inside methods.
  5. Apr 2021
    1. It seems inelegant to me to split this into two different modules, one to include, the other to extend.

      the key thing (one of them) to understand here is that: class methods are singleton methods

    2. Another possible solution would be to use a class Common instead of a module. But this is just a workaround.
    3. Trust this answer. This is a very common idiom in Ruby, solving precisely the use case you ask about and for precisely the reasons you experienced. It may look "inelegant", but it's your best bet.
    1. Apparently when you create a subclass, that subclass's singleton class has # its superclass's singleton class as an ancestor.

      This is a good thing. It allows class methods to be inherited by subclasses.

    2. at least in recent versions of Ruby, calling ancestors on the singleton class does show the other singleton classes.
    3. I played around with something to give me the list of receivers for any Ruby object in my introspection gem. If you load the "introspection/receivers" file you get a method #receivers on any object which gives you the whole receiver chain.
  6. Mar 2021
    1. Not enjoying Xcode, Amir used RubyMotion instead. Amir had real-world experience with Xcode and Objective-C, but didn't like it at all. Amir also has a Ruby background and went with RubyMotion to build A Dark Room. The command-line interface, the testing framework, the gems libraries and the CocoaPods integration and the freedom to use any text editor contributed to his decision.
    1. # Parallel Ruby universes ("Rubyverses") - A proposed interface for # parallel, "semi-private" method or method-and-data spaces via # "closely associated" objects.
    1. A proposal to specify the path for bury with classes as values of a hash arg: {}.bury(users: Array, 0 => Hash, name: Hash, something: 'Value') # {user: [{name: {something: 'Value'}]} So all absent nodes could be created via klass.new

      Didn't understand it at first, but now I think it's a pretty clever/decent solution.

      Just a bit more verbose than one might like...

      At first I had reservations about the fact that this requires you to pass a hash ... or rather, once you start using a hash as your "list", you can't just "switch back" to an array (a "problem" I've noticed in RSpec, where you have some tags that are symbols, and some that are hashes: you have to list the symbols first: describe 'thing', :happy_path, driver: :chrome):

      {}.bury(users: Array, 0, 'Value')

      But I think that's okay in practice. Just use a hash for all "elements" in your list:

      {}.bury(users: Array, 0 => 'Value')
    2. I think the issues/problems specified in the comments are not present with a Hash-only implementation. :) I would be supportive of re-considering this feature just for use with a Hash, where I believe 80% of the real-life use cases would (and do) exist. I have encountered this need before in the wild, but not with Arrays.
    3. In fact, I'm only here because it seems like something one would 'expect' ruby already to do.
    1. can you break this, thouugh? like can you override kind_of? but not is_a?
    2. It just reads better sometimes. Think @honda.kind_of? Car and @person.is_a? Administrator, Ruby's all about the aesthetics.
    3. As to why both is_a? and kind_of? exist: I suppose it's part of Ruby's design philosophy. Python would say there should only be one way to do something; Ruby often has synonymous methods so you can use the one that sounds better. It's a matter of preference.
    1. #!/usr/bin/env ruby txmt_param = ARGV[0] txmt_path = txmt_param.match("%2F.*&").to_s txmt_path = txmt_path [0...-1] txmt_path_slashed = txmt_path.gsub("%2F","/") txmt_line = txmt_param.match("&line=.*").to_s txmt_line = txmt_line [6..txmt_line.length] vim_params = Array.new vim_params = "--remote-tab-silent" vim_params << " +#{txmt_line}" if txmt_line vim_params << " #{txmt_path_slashed}"
    1. Opal is a Ruby to JavaScript source-to-source compiler. It comes packed with the Ruby corelib you know and love. It is both fast as a runtime and small in its footprint.
    1. Notice that the HTML elements (BUTTON, DIV, etc.) are in CAPS. We know this is bending the standard Ruby style rules slightly, but we think it reads better this way.
    2. we used `backticks` to jump into native Javascript to use moment.js

      In regular Ruby, `` executes in a shell, but obviously there is no shell of that sort in JS, so it makes sense that they could (and should) repurpose that syntax for something that makes sense in context of JS -- like running native JavaScript -- prefect!

    3. Hyperstack gives you full access to the entire universe of JavaScript libraries and components directly within your Ruby code.Everything you can do in JavaScript is simple to do in Ruby; this includes passing parameters between Ruby and JavaScript and even passing Ruby methods as JavaScript callbacks.There is no need to learn JavaScript, all you need to understand is how to bridge between JS and Ruby.
    1. One day last August 2018, I stumbled upon an online petition that sparked my curiosity - We Want Serverless Ruby. At that time, none of the major cloud providers had first-class support for Ruby in their serverless products. There were ~1400 devs signing that petition, and I wondered if there was something about Ruby that made it unsuitable for FaaS. I decided to roll the sleeves and start building what would be the first PoC of faastRuby.
    1. Using ::delegates works exactly like the Forwardable module in Ruby, with one bonus: It creates the accessors in a module, allowing you to override and call super in a user module or class.
    2. Uber::Option implements the pattern of taking an option, such as a proc, instance method name, or static value, and evaluate it at runtime without knowing the option's implementation.
    1. The absence of a method name here is per design: this object does only one thing, and hence what it does is reflected in the class name.
    1. There’s no additional logic from Trailblazer happening here. The function returns a well-defined hash which is passed as an argument to step.
  7. Feb 2021
    1. # Yes, you can use lambdas as steps, too! step ->(ctx, params:, **) { params.is_a?(Hash) }
    2. Keyword arguments allow to define particular parameters as required. Should the parameter be missing, they also provide a way to set a default value. This is all done with pure Ruby.
    3. a task in an activity can be any callable Ruby object
    4. Your actual logic happens in tasks, the labeled boxes. A task may be any callable Ruby object, an instance method or even another activity.
    5. Trailblazer is an architectural pattern that comes with Ruby libraries to implement that pattern.
    1. Please note that the actual task doesn’t have to be a proc! Use a class, constant, object, as long as it exposes a #call method it will flow.
    2. You may use keyword arguments in your filters for type safety and better readable code.
    1. Operations define the flow of their logic using the DSL and implement the particular steps with pure Ruby.
    1. Yes, Trailblazer is adding new abstractions and concepts and they are different to the 90s-Ruby, but now, at the latest, it becomes obvious how this improves the developing process. We’re no longer talking in two-dimensional method stack traces or byebug hoops, the language and conception is changing to the actual higher level code flow, to activities sitting in activities structured into smaller step units.
    1. There are times where it is useful to know whether a value was passed to run or the result of a filter default. In particular, it is useful when nil is an acceptable value.

      Yes! An illustration in ruby:

      main > h = {key_with_nil_value: nil}
      => {:key_with_nil_value=>nil}
      main > h[:key_with_nil_value]
      => nil
      main > h[:missing_key]  # this would be undefined in JavaScript (a useful distinction) rather than null, but in Ruby it's indistinguishable from the case where a nil value was actually explicitly _supplied_ by the caller/user
      => nil
      # so we have to check for "missingness" ("undefinedness"?) differently in Ruby
      main > h.key?(:key_with_nil_value)
      => true
      main > h.key?(:missing_key)
      => false

      This is one unfortunate side effect of Ruby having only nil and no built-in way to distinguish between null and undefined like in JavaScript.

    1. The problem is that you what you want is actually not de-structuring at all. You’re trying to go from 'arg1', { hash2: 'bar', hash3: 'baz' }, { hash1: 'foo' } (remember that 'arg1', foo: 'bar' is just shorthand for 'arg1', { foo: 'bar' }) to 'arg1', { hash1: 'foo', hash2: 'bar', hash3: 'baz' } which is, by definition, merging (note how the surrounding structure—the hash—is still there). Whereas de-structuring goes from 'arg1', [1, 2, 3] to 'arg1', 1, 2, 3
    1. {a: 1, b: 2, c: 3, d: 4} => {a:, b:, **rest} # a == 1, b == 2, rest == {:c=>3, :d=>4}

      equivalent in javascript:

      {a, b, ...rest} = {a: 1, b: 2, c: 3, d: 4}

      Not a bad replacement for that! I still find javascript's syntax a little more easily readable and natural, but given that we can't use the same syntax (probably because it would be incompatible with existing syntax rules that we can't break for compatibility reasons, unfortunately), this is a pretty good compromise/solution that they've come up with.

    2. You can rescue at the method level, but more likely you’d want to rescue at the statement level.
    3. (Yay for the hashrocket resurgence!)
    4. we’re going to look how improved pattern matching and rightward assignment make it possible to “destructure” hashes and arrays in Ruby 3—much like how you’d accomplish it in, say, JavaScript
    1. Nevermind, I use now reform-rails
    2. @adisos if reform-rails will not match, I suggest to use: https://github.com/orgsync/active_interaction I've switched to it after reform-rails as it was not fully detached from the activerecord, code is a bit hacky and complex to modify, and in overall reform not so flexible as active_interaction. It has multiple params as well: https://github.com/orgsync/active_interaction/blob/master/spec/active_interaction/modules/input_processor_spec.rb#L41

      I'm not sure what he meant by:

      fully detached from the activerecord I didn't think it was tied to ActiveRecord.

      But I definitely agree with:

      code is a bit hacky and complex to modify

    3. you can do pairs.each_with_object({}) do |(multiparameter_name, value), attributes|
    4. values_with_empty_parameters.each_value.all?(&:nil?) This comment has been minimized. Show comment Hide comment Copy link Quote reply egilburg on Apr 9, 2015 Contributor you can do values_with_empty_parameters.values.none? [nil, nil].none? => true Pick your reaction egilburg on Apr 9, 2015 Contributor you can do values_with_empty_parameters.values.none? [nil, nil].none? => true
    1. Set your models free from the accepts_nested_attributes_for helper. Action Form provides an object-oriented approach to represent your forms by building a form object, rather than relying on Active Record internals for doing this.

      It seems that the primary/only goal/purpose was to provide a better alternative to ActiveRecord's accepts_nested_attributes_for.

      Unfortunately, this appears to be abandoned.

    1. Set your models free from the accepts_nested_attributes_for helper. Active Form provides an object-oriented approach to represent your forms by building a form object, rather than relying on Active Record internals for doing this.
  8. Jan 2021
  9. Dec 2020
  10. ttytoolkit.org ttytoolkit.org