I would like to be able to programmatically compose a chain, for later inclusion in another chain. I know it can't be that hard, but I seem to be missing something.
In theory, I should be able to do something like this:
var c = ??? // the part I can't figure out
List( 1, 2, 3 ).foreach {
c.exec( http("Fetch something").get("..." + _ ) )
}
That is, I expect to be able to create a chain, then populate that chain in a loop, rather than hard-coding the chain in the source code.
My biggest struggle, I think, is knowing what to assign to c. I had assumed that it should be
var c = new ChainBuilder()
but according to the documentation I have to pass it a list of actionBuilders and the next action, implying that it is not possible to build an empty chain and then build on it in a separate statement.
Is there any way to make my .foreach loop work the way I intend it to work?
The answer is
import bootstrap._
and then
var c = bootstrap
But then the loop must be modified, like so:
List( 1, 2, 3 ).foreach( x => {
c = c.exec( ... )
})
The reason has to do with the fact that you have to do what chaining does. When you have
foo()
.bar()
.blip()
The result of the whole expression is the return value from blip and not foo - which is obvious when you think about it - so the variable that we are attaching to has to move as nodes are attached.
I hope someone, somewhere, besides me, finds value in seeing this example.
Related
Learning react here. Can someone walk me through how to interpret the function below:
const onElementsRemove = (elementsToRemove) => setElements((els) => removeElements(elementsToRemove, els));
As far as I understand it, this is the same as calling:
onElementsRemove(setElements(elementsToRemove(els))?
Is that correct? Is there a benefit to the first notation? Perhaps I am biased coming from the python side of the world but the second one feels more compact? Can someone help me undrstand the reasoning? Thanks!
No, those are not the same. Let's start with the inner part, which needs to be the way it is:
setElements((els) => removeElements(elementsToRemove, els))
When setting state in react, there are two options. You can either directly pass in what you want the new state to be, or you can pass in a function. If you pass in a function, then react will look up what the latest value of the state is, and call your function. Then you return what the new state will be.
So the purpose of doing it this way is to find out what the latest value in the state is. There isn't another way to do this.
Next, the outer part, which has more flexibility:
const onElementsRemove = (elementsToRemove) => /* the stuff we looked at earlier */
This is defining a function called onElementsRemove. From the name, i assume that this is going to be called at some arbitrary point of time in the future. So it's just defining the functionality, and later on you can call it, once you know which elements you want to remove. It will then turn around and set the state. For example, you would do:
onElementsRemove([1, 2, 3]); // i don't actually know what will be in the array
Maybe having this outer function is useful, maybe not. If you're having to do this fairly often it could make sense. In other cases, maybe you could directly call setElements, as in:
setElements((els) => removeElements([1, 2, 3], els));
I have some ruby code from my Ruby on Rails project.
I am formatting some data so I am calling attributes.extract! to get the fields I need from my model.
I noticed recently that every now and then the data wouldn't get extracted as expected. I realized that I needed a splat operator. But it is strange because I do notice that sometimes when the method is called in my Rails project it will sometimes extract the data without the use of the splat operator. But when I run the code from my Rails console it never extracts the data unless I add the splat operator.
Here is the code in question
# in a service file, let's call it service.rb
def self.format_user_home_address_data(user)
# This doesn't work in the console but sometimes works when run in my Rails project
home_address_data = user.attributes.extract!(User::HOME_ADDRESS_FIELDS)
home_address_data[:address_type] = "home"
home_address_data
end
# at the end this method will sometimes return { address_type: "home" } or
# sometimes it'll actually return the extracted attributes as expected
HOME_ADDRESS_FIELDS is just an array with the values ["address_line_1", "city", "state", "zip"]
Anyway I know that to get it to run correctly I need to do this
home_address_data = user.attributes.extract!(*User::HOME_ADDRESS_FIELDS)
But does anyone know why I was able to get away without adding the splat operator for so long? Is there some Ruby on Rails magic that is only sometimes happening? What's the deal?
Well, let's check it out. There is no any magic behind attributes.extract! in the end. Here is an actual implementation of this method from Rails source code:
def extract!(*keys)
keys.each_with_object(self.class.new) { |key, result|
result[key] = delete(key) if has_key?(key)
}
end
Link: click. As you can see, it creates new hash, goes over the keys one by one and moves value from self to this new array. So, if you give an Array argument to this method then key in the block will be an Array as well. So, it won't be found. So, no way it may work for array argument. The only one possibility is that something else is passed instead of User::HOME_ADDRESS_FIELDS.
I've been working on Ruby Koans and I've gotten to this part that I don't understand too well. Specifically, it's the about_dice_project, where they ask us to define a class to pass several pre-set tests. Originally, my class looked like
class DiceSet
attr_accessor :values
def initialize
#values = []
end
def roll(num)
num.times { |i| #values[i] = rand(1..6) }
return #values
end
end
But this failed the test below
dice = DiceSet.new
dice.roll(5)
first_time = dice.values
dice.roll(5)
second_time = dice.values
assert_not_equal first_time, second_time,
"Two rolls should not be equal"
And I realized after some testing that both first_time and second_time have the same object_id. So I looked on stackoverflow for some help and found this answer, which doesn't answer my question directly, but I did find a major difference in our code; namely, that instead of using the "num.times" way of rolling the dice, goes instead with
#values = Array.new(num) { rand(1..6) }
and this does pass the above test.
After finding this, I was trying to figure out why my original code didn't work, and so I thought that maybe Ruby was passing by reference, and that's why when the dice-rolling-method created a new array instead of modifying the existing array, that was a new object id created. But then I found this question, which says that Ruby is pass-by-value, and if that was the case, then I would have expected that my original way would work.
So now I'm confused again, and I'd like to ask - where did my line of thought go wrong? Is Ruby pass-by-value only in certain cases? Have I misunderstood what pass-by-value/reference even means? Is my issue not related to pass-by-value/reference at all?
You can see object in ruby as a reference to data.
So even if Ruby is pass by value, the thing got copy is object, a.k.a a handle to underlining data.
Even from the answer you link to, had said:
Variables are always references to objects. In order to get an object that won't change out from under you, you need to dup or clone the object you're passed, thus giving an object that nobody else has a reference to. (Even this isn't bulletproof, though — both of the standard cloning methods do a shallow copy, so the instance variables of the clone still point to the same objects that the originals did. If the objects referenced by the ivars mutate, that will still show up in the copy, since it's referencing the same objects.)
Ruby 2.3 introduces a new method on Array and Hash called dig. The examples I've seen in blog posts about the new release are contrived and convoluted:
# Hash#dig
user = {
user: {
address: {
street1: '123 Main street'
}
}
}
user.dig(:user, :address, :street1) # => '123 Main street'
# Array#dig
results = [[[1, 2, 3]]]
results.dig(0, 0, 0) # => 1
I'm not using triple-nested flat arrays. What's a realistic example of how this would be useful?
UPDATE
It turns out these methods solve one of the most commonly-asked Ruby questions. The questions below have something like 20 duplicates, all of which are solved by using dig:
How to avoid NoMethodError for missing elements in nested hashes, without repeated nil checks?
Ruby Style: How to check whether a nested hash element exists
In our case, NoMethodErrors due to nil references are by far the most common errors we see in our production environments.
The new Hash#dig allows you to omit nil checks when accessing nested elements. Since hashes are best used for when the structure of the data is unknown, or volatile, having official support for this makes a lot of sense.
Let's take your example. The following:
user.dig(:user, :address, :street1)
Is not equivalent to:
user[:user][:address][:street1]
In the case where user[:user] or user[:user][:address] is nil, this will result in a runtime error.
Rather, it is equivalent to the following, which is the current idiom:
user[:user] && user[:user][:address] && user[:user][:address][:street1]
Note how it is trivial to pass a list of symbols that was created elsewhere into Hash#dig, whereas it is not very straightforward to recreate the latter construct from such a list. Hash#dig allows you to easily do dynamic access without having to worry about nil references.
Clearly Hash#dig is also a lot shorter.
One important point to take note of is that Hash#dig itself returns nil if any of the keys turn out to be, which can lead to the same class of errors one step down the line, so it can be a good idea to provide a sensible default. (This way of providing an object which always responds to the methods expected is called the Null Object Pattern.)
Again, in your example, an empty string or something like "N/A", depending on what makes sense:
user.dig(:user, :address, :street1) || ""
One way would be in conjunction with the splat operator reading from some unknown document model.
some_json = JSON.parse( '{"people": {"me": 6, ... } ...}' )
# => "{"people" => {"me" => 6, ... }, ... }
a_bunch_of_args = response.data[:query]
# => ["people", "me"]
some_json.dig(*a_bunch_of_args)
# => 6
It's useful for working your way through deeply nested Hashes/Arrays, which might be what you'd get back from an API call, for instance.
In theory it saves a ton of code that would otherwise check at each level whether another level exists, without which you risk constant errors. In practise you still may need a lot of this code as dig will still create errors in some cases (e.g. if anything in the chain is a non-keyed object.)
It is for this reason that your question is actually really valid - dig hasn't seen the usage we might expect. This is commented on here for instance: Why nobody speaks about dig.
To make dig avoid these errors, try the KeyDial gem, which I wrote to wrap around dig and force it to return nil/default if any error crops up.
I was wondering if anyone knew if you perform a SCNAction on a node, is there a way while that node is executing the action, where you could find out what position it's in the scenes coordinate system?
Lets say I have two SCNNodes A and B...
SCNNode *A, *B;
and I want to run a SCNAction for A
A.position = SCNVector3Make(0.0,0.0,0.0);
[A runAction:[SCNAction moveTo:SCNVector3Make(10.0,0.0,0.0)]];
and while A was running its action, have B follow it in real time?
[B runAction:[SCNAction repeatActionForever:[SCNAction moveTo:A.position]]];
So every time B repeats its given a new updated position of A to move to.
The problem I'm getting is, even if I set the presentationNode of A to the SCNAction above, It's still returning the initial input that I set (which makes sense) but how do I get the updated position of A?
Side Note: When I take A.presentationNode.position I get the default Zero Vector
SOLVED QUESTION
After further research, I found out how to use the SCNSceneRendererDelegate and then created a (void) method which updated the position of node A and then within the same method I had a SCNAction which moved B to the update position of A.
If anyone had a similar issue or would just like to see the code, let me know and I'll post it!
A.position is evaluated once and only once, when you create the action:
[SCNAction moveTo:A.position]
There is no block involved here that gives you a chance to customize the action as time passes.
I know this is an old question, but you could have used a SCNDistanceConstraint with a distance of zero.
You could also simply have created a property on B that you assign A to. Then, for B, use a custom action to access that. e.g.
class BNode : SCNNode
var ANodeInstance : SCNNode? = nil
init(withANode: SCNNode) {
super.init()
self.ANodeInstance = withANode
}
}
B.runAction(SCNAction.repeatActionForever(
SCNAction.customAction(duration: duration, action: { (node, timeElapsed) in
let selfAsBNode = node as! BNode
selfAsBNode.position = selfAsBNode.ANodeInstance.position
})
Sorry, it's in Swift not Objective-C but it's pretty easy to translate back.
This sort of thing is ugly as blazes, but Apple haven't really provided any clean way to communicate state through a chain of actions.