在Ruby中通过标识比较两个对象的保证方法是什么?给定两个变量,如果变量指向内存中完全相同的对象,我想返回true.
对于大多数Ruby对象,该equal?方法按身份进行比较:
f = g = Object.new
p f.equal? g # => true
Run Code Online (Sandbox Code Playgroud)
但是,这不适用于所有对象.例如:
class F
def ==(obj) false end
def ===(obj) false end
def eql?(obj) false end
def equal?(obj) false end
def object_id; self end
end
f = g = F.new
p f == g # => false
p f === g # => false
p f.eql? g # => false
p f.equal? g # => false
p f.object_id == g.object_id # => false
Run Code Online (Sandbox Code Playgroud)
什么是通过身份比较两个对象的万无一失的保证方法?
这是一个纯粹的智力问题.任何以"为什么"开头的问题的答案都可能是"因为我很好奇".
我正在使用YARD为我的ruby gem编写文档.在我的gem中,我有一些代码遵循这个常见的ruby模式,其中一个模块包含在一个类中,该模块不仅添加了实例方法,还添加了类方法:
module Moo
def self.included(klass)
klass.extend ClassMethods
end
module ClassMethods
def hello
puts "hello"
end
end
end
class Foo
include Moo
end
Foo.hello # => class method runs, printing "hello"
Run Code Online (Sandbox Code Playgroud)
默认情况下,YARD将生成Foo类的文档,如下所示:

我认为这个文档是不合适的,因为它没有告诉用户该Foo.hello方法是可用的.要了解hello,用户必须单击Moo,然后单击ClassMethods.
Foo在一个页面上拥有所有类和实例方法的列表会很棒.我怎么能做到这一点?我是否需要更改代码,或者是否有我可以添加的标签给YARD一个提示ClassMethods?
我正在尝试编写Ruby代码来检查我在此处找到的特定消息上的椭圆曲线数字签名算法(ECDSA)签名.
问题是我不知道如何将公钥的八位字节串转换为OpenSSL :: PKey :: EC :: Point对象.如果我用C语言写这个,我只是将八位字节字符串传递给OpenSSL o2i_ECPublicKey,它做了一些接近我想要的东西,实际上是由参考实现使用的.但是,我搜索了Ruby(MRI)的源代码并且它不包含任何调用,o2i_ECPublicKey因此我不知道如何在不编写C扩展的情况下从Ruby中使用该函数.
这是十六进制的八位字符串.它只是一个0x04字节,后跟两个32字节整数,表示椭圆曲线上点的x和y坐标:
04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284
Run Code Online (Sandbox Code Playgroud)
那么有谁知道如何将该字符串转换为OpenSSL::PKey::EC::PointRuby 中的in?一旦我得到了点对象,我将在下面的代码中使用它,我认为这将验证签名:
key = OpenSSL::PKey::EC.new('secp256k1')
key.public_key = point
result = key.dsa_verify_asn1(digest, signature)
Run Code Online (Sandbox Code Playgroud)
更新:
感谢Jay-Ar Polidario,我得到了它的工作.以下是我使用OpenSSL验证签名的完整代码.我还写了一个名为ecdsa的宝石,我包含的代码显示了如何使用我的宝石做同样的事情.
# coding: ASCII-8BIT
digest =
"\xbf\x91\xfb\x0b\x4f\x63\x33\x77\x4a\x02\x2b\xd3\x07\x8e\xd6\xcc" \
"\xd1\x76\xee\x31\xed\x4f\xb3\xf9\xaf\xce\xb7\x2a\x37\xe7\x87\x86"
signature_der_string =
"\x30\x45" \
"\x02\x21\x00" \
"\x83\x89\xdf\x45\xf0\x70\x3f\x39\xec\x8c\x1c\xc4\x2c\x13\x81\x0f" \
"\xfc\xae\x14\x99\x5b\xb6\x48\x34\x02\x19\xe3\x53\xb6\x3b\x53\xeb" \
"\x02\x20" \
"\x09\xec\x65\xe1\xc1\xaa\xee\xc1\xfd\x33\x4c\x6b\x68\x4b\xde\x2b" \
"\x3f\x57\x30\x60\xd5\xb7\x0c\x3a\x46\x72\x33\x26\xe4\xe8\xa4\xf1"
public_key_octet_string =
"\x04" \
"\xfc\x97\x02\x84\x78\x40\xaa\xf1\x95\xde\x84\x42\xeb\xec\xed\xf5" \
"\xb0\x95\xcd\xbb\x9b\xc7\x16\xbd\xa9\x11\x09\x71\xb2\x8a\x49\xe0" \
"\xea\xd8\x56\x4f\xf0\xdb\x22\x20\x9e\x03\x74\x78\x2c\x09\x3b\xb8" \
"\x99\x69\x2d\x52\x4e\x9d\x6a\x69\x56\xe7\xc5\xec\xbc\xd6\x82\x84"
# Verifying with …Run Code Online (Sandbox Code Playgroud) 出于某种原因,我找不到任何提及如何执行此操作的教程...那么,如何从文件中读取前n行?
我想出来:
while File.open('file.txt') and count <= 3 do |f|
...
count += 1
end
end
Run Code Online (Sandbox Code Playgroud)
但它不起作用,对我来说也不是很好看.
出于好奇,我尝试过这样的事情:
File.open('file.txt').10.times do |f|
Run Code Online (Sandbox Code Playgroud)
但那也没有用.
那么,有没有一种简单的方法来读取前n行而不必加载整个文件?非常感谢你!
我正在为USB设备编写代码.假设USB主机启动控制读取传输以从设备读取一些数据,并且请求的数据量(设置数据包中的wLength)是端点0最大数据包大小的倍数.然后在主机收到所有数据(以几个具有最大数据包的IN事务的形式)之后,它是否会启动另一个IN事务以查看是否有更多数据,即使没有更多数据?
以下是我想知道的一系列事件示例:
我在我的计算机上测试了这个(Windows Vista,如果它很重要),答案是否定的:主机足够聪明,知道无法从设备接收到更多数据,即使设备发送的所有数据包都已满(端点0上允许的最大大小.我想知道是否有任何主机不够智能,并将尝试执行另一个IN事务并期望接收零长度数据包.
我想我从usb.org上读到了USB 2.0和USB 3.0规范的相关部分,但我没有发现这个问题.如果有人能指出我在其中任何一个文件中的正确部分,我将不胜感激.
我知道如果设备选择发送的数据少于wLength中请求的主机,则可能需要零长度数据包.
我知道我可以使我的代码足够灵活,以处理任何一种情况,但我希望我没有必要.
感谢任何能够回答这个问题的人!
我是Java世界的新手,但我熟悉Ruby.我正在尝试编写一个与某些第三方jar文件交互的程序.
虽然从Java调用库似乎表现得很好,但是当我在JRuby中调用它们时它们的行为不正确.这是一个问题因为我真的想使用JRuby.例如,下面的两个程序尝试完全相同的东西,但它们产生不同的输出:
我在Netbeans中开发了下面的Java程序,然后按F6(运行主项目)运行它.项目的Libraries文件夹设置为"C:\ Program Files(x86)\ Microchip\MPLABX\mplab_ide\lib \nblibraries.properties".当我运行它时,它会打印"pins:17".
package pinbug1;
import com.microchip.mplab.mdbcore.assemblies.Assembly;
import com.microchip.mplab.mdbcore.assemblies.AssemblyFactory;
import com.microchip.mplab.mdbcore.simulator.PinSet;
import com.microchip.mplab.mdbcore.simulator.Simulator;
import org.openide.util.Lookup;
public class PinBug1
{
public static void main(String[] args)
{
AssemblyFactory assemblyFactory = Lookup.getDefault().lookup(AssemblyFactory.class);
Assembly assembly = assemblyFactory.Create("PIC18F14K50");
Simulator simulator = assembly.getLookup().lookup(Simulator.class);
int num = simulator.getDataStore().getProcessor().getPinSet().getNumPins();
System.out.println("pins: " + num); // prints "pins: 17"
}
}
Run Code Online (Sandbox Code Playgroud)
我只需输入就运行下面的JRuby程序jruby bug_reproduce.rb并打印"pins:0".我希望它像Java程序一样打印"pins:17".
["mplab_ide/mdbcore/modules/*.jar",
"mplab_ide/mplablibs/modules/*.jar",
"mplab_ide/mplablibs/modules/ext/*.jar",
"mplab_ide/platform/lib/org-openide-util*.jar",
"mplab_ide/mdbcore/modules/ext/org-openide-filesystems.jar"
].each do |pattern|
Dir.glob("C:/Program Files (x86)/Microchip/MPLABX/" + pattern).each do |x|
require x
end
end …Run Code Online (Sandbox Code Playgroud) LLVM 语言参考说明了这一点
整数类型是一种非常简单的类型,它只是为所需的整数类型指定任意位宽.可以指定从1位到2 23 -1(大约8百万)的任何位宽.
这是否意味着我可以免费使用任意固定长度的整数?也就是说,如果我声明一个i100,我会有一个100位宽的变量吗?
我有一段用C编写的代码,其中执行了一些指针算法.我想知道输出是怎么来的?
#include <stdio.h>
int main()
{
char arr[] = "gookmforgookm";
char *ptr1 = arr;
char *ptr2 = ptr1 + 3;
printf ("ptr2 - ptr1 = %d\n", ptr2 - ptr1);
printf ("(int*)ptr2 - (int*) ptr1 = %d", (int*)ptr2 - (int*)ptr1);
getchar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出如下:
ptr2 - ptr1 = 3
(int*)ptr2 - (int*) ptr1 = 0
Run Code Online (Sandbox Code Playgroud) 我们构建项目的Jenkins工作触发了几个GIT存储库的主服务器的更改.当它开始构建时,它会清理所有repo checkout的工作区.我们希望仅将作业用于请求的清理构建,默认情况下用于增量构建.我们生成的一些代码(仍)在结账时生成,因此需要进行清理,因此每次运行都需要重新生成和构建.这需要我们想要摆脱的相当多的时间.
注意构建日志的这一部分的最后一行:
Started by user jenkins
Building on master
Checkout:WORK_PLATFORM3_REL_BUILD / /home/jenkins/data/WORK_PLATFORM3_REL_BUILD - hudson.remoting.LocalChannel@116fc35
Using strategy: Default
Last Built Revision: Revision 5479a644c63e128efb4fa61c00b4a708d8ae594f (origin/master)
Checkout:xxxxxx / /home/jenkins/data/WORK_PLATFORM3_REL_BUILD/xxxxxxx - hudson.remoting.LocalChannel@116fc35
Fetching changes from 1 remote Git repository
Fetching upstream changes from ssh://jenkinslinux@git.xxxxxxx.com:29418/xxxxxxx
Commencing build of Revision 5479a644c63e128efb4fa61c00b4a708d8ae594f (origin/master)
Checking out Revision 5479a644c63e128efb4fa61c00b4a708d8ae594f (origin/master)
Cleaning workspace
Run Code Online (Sandbox Code Playgroud)
我找不到作业配置中的设置来禁用此"清理工作区",也无法使用任何全局设置来更改此设置.
有解决方案吗?
顺便说一句,我们正在运行Jenkins 1.410(关于主题:升级到最新版本是一项微不足道的任务吗?)
我是Haskell的初学者,我正在研究一些使用Either进行错误处理的Haskell代码.Either的左侧元素表示错误,而右侧元素表示成功结果.代码经常使用Either的Applicative实例,它似乎是为这个用例设计的.
给定一个类型的对象,[Either e r]将它变成类型对象的最优雅的方法是什么Either e [r]?这一点的意思是我们可能有一些来自我们调用的函数的返回值数组,如果这些返回值中的任何一个是错误,我们希望得到该错误并抛弃其他所有内容.如果数组的多个元素有错误,我希望尽可能得到最左边的错误.
通过编写两个函数,我能够在下面的代码中自己解决这个问题,其中一个函数是递归的,但是有更好的方法吗?
type Error = [Char]
myFunc :: [Either Error a] -> Either Error [a]
myFunc = myFunc2 []
myFunc2 :: [a] -> [Either Error a] -> Either Error [a]
myFunc2 r ((Left error):rest) = Left error
myFunc2 r ((Right item):rest) = myFunc2 (r ++ [item]) rest
myFunc2 r [] = Right r
main :: IO()
main = do
-- This prints: Right [1, 2, 3]
putStrLn (show (myFunc …Run Code Online (Sandbox Code Playgroud)